Changeset 87615a48 in sasview for sansmodels/src/sans


Ignore:
Timestamp:
Jun 9, 2011 10:46:26 AM (14 years ago)
Author:
Jae Cho <jhjcho@…>
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
5d2b35a
Parents:
7b3bbbe
Message:

added c-extension for smearer2d_helper(but locked it for now)

Location:
sansmodels/src/sans/models
Files:
3 added
1 edited

Legend:

Unmodified
Added
Removed
  • sansmodels/src/sans/models/smearing_2d.py

    r6e8b436 r87615a48  
    1010import numpy 
    1111import math 
     12 
    1213## Singular point 
    1314SIGMA_ZERO = 1.0e-010 
     
    1617LIMIT = 3.0 
    1718## Defaults 
    18 R_BIN = {'Xhigh':10.0, 'High':5.0,'Med':5.0,'Low':3.0} 
    19 PHI_BIN ={'Xhigh':20.0,'High':12.0,'Med':6.0,'Low':4.0}    
     19R_BIN = {'Xhigh':10, 'High':5,'Med':5,'Low':3} 
     20PHI_BIN ={'Xhigh':20,'High':12,'Med':6,'Low':4}    
    2021 
    2122class Smearer2D: 
     
    2526      
    2627    def __init__(self, data=None, model=None, index=None,  
    27                  limit=LIMIT, accuracy='Low', coords='polar'): 
     28                 limit=LIMIT, accuracy='Low', coords='polar', engine='python'): 
    2829        """ 
    2930        Assumption: equally spaced bins in dq_r, dq_phi space. 
     
    3536        :param nphi: number of bins in dq_phi-axis 
    3637        :param coord: coordinates [string], 'polar' or 'cartesian' 
     38        :param engine: engine name [string]; 'c' or 'numpy' 
    3739        """ 
    3840        ## data 
     
    5153        self.coords = coords 
    5254        self.smearer = True 
     55        self._engine = engine 
    5356         
    5457         
     
    119122        Over sampling of r_nbins times phi_nbins, calculate Gaussian weights,  
    120123        then find smeared intensity 
    121         For the default values, this is equivalent (but by using numpy array  
    122         the speed optimized by a factor of ten)to the following: :: 
    123         
    124         
    125         Remove the singular points if exists 
    126         self.dqx_data[self.dqx_data==0]=SIGMA_ZERO 
    127         self.dqy_data[self.dqy_data==0]=SIGMA_ZERO 
    128          
    129         for phi in range(0,4): 
    130             for r in range(0,5): 
    131                 n = (phi)*5+(r) 
    132                 r = r+0.25 
    133                 dphi = phi*2.0*math.pi/4.0 + numpy.arctan( \ 
    134                         self.qy_data[index_model]/self.dqy_data[index_model]/ \ 
    135                         self.qx_data[index_model]*/self.dqx_data[index_model]) 
    136                 dq = r*sqrt( self.dqx_data[index_model]*\ 
    137                         self.dqx_data[index_model] \ 
    138                     + self.dqy_data[index_model]*self.dqy_data[index_model] ) 
    139                 #integrant of exp(-0.5*r*r) r dr at each bins :  
    140                 The integration may not need. 
    141                 weight_res[n] = e^{(-0.5*((r-0.25)*(r-0.25)))}- \ 
    142                                 e^{(-0.5*((r-0.25)*(r-0.25)))} 
    143                 #if phi != 0 and r != 0: 
    144                 qx_res = numpy.append(qx_res,self.qx_data[index_model]+ \ 
    145                                                             dq * cos(dphi)) 
    146                 qy_res = numpy.append(qy_res,self.qy_data[index_model]+ \ 
    147                                                             dq * sin(dphi)) 
    148                      
    149         Then compute I(qx_res,qy_res) and do weighted averaging.  
    150          
    151         """ 
     124        """     
    152125        valid = self.get_data() 
    153126        if valid == None: 
     
    163136        nr = self.nr[self.accuracy] 
    164137        nphi = self.nphi[self.accuracy] 
    165  
    166         # data length in the range of self.index 
    167         len_data = len(self.qx_data) 
    168         len_datay = len(self.qy_data) 
    169  
    170138        # Number of bins in the dqr direction (polar coordinate of dqx and dqy) 
    171139        bin_size = self.limit / nr 
     
    173141        # in dq_r-direction times # of bins in dq_phi-direction 
    174142        n_bins = nr * nphi 
    175         # Mean values of dqr at each bins ,starting from the half of bin size 
    176         r = bin_size / 2.0 + numpy.arange(nr) * bin_size 
    177         # mean values of qphi at each bines 
    178         phi = numpy.arange(nphi) 
    179         dphi = phi * 2.0 * math.pi / nphi 
    180         dphi = dphi.repeat(nr) 
    181  
    182         ## Transform to polar coordinate,  
    183         #  and set dphi at each data points ; 1d array 
    184         dphi = dphi.repeat(len_data) 
    185         q_phi = self.qy_data / self.qx_data 
    186          
    187         # Starting angle is different between polar and cartesian coordinates. 
    188         #if self.coords != 'polar': 
    189         #    dphi += numpy.arctan( q_phi * self.dqx_data/ \ 
    190         #                     self.dqy_data).repeat(n_bins).reshape(len_data,\ 
    191         #                                        n_bins).transpose().flatten() 
    192  
    193         # The angle (phi) of the original q point 
    194         q_phi = numpy.arctan(q_phi).repeat(n_bins).reshape(len_data,\ 
    195                                                 n_bins).transpose().flatten() 
    196         ## Find Gaussian weight for each dq bins: The weight depends only  
    197         #  on r-direction (The integration may not need) 
    198         weight_res = numpy.exp(-0.5 * ((r - bin_size / 2.0) * \ 
    199                                     (r - bin_size / 2.0)))- \ 
    200                                     numpy.exp(-0.5 * ((r + bin_size / 2.0 ) *\ 
    201                                     (r + bin_size / 2.0))) 
    202         # No needs of normalization here. 
    203         #weight_res /= numpy.sum(weight_res) 
    204         weight_res = weight_res.repeat(nphi).reshape(nr, nphi) 
    205  
    206         weight_res = weight_res.transpose().flatten() 
    207          
    208         ## Set dr for all dq bins for averaging 
    209         dr = r.repeat(nphi).reshape(nr,nphi).transpose().flatten() 
    210         ## Set dqr for all data points 
    211         dqx = numpy.outer(dr,self.dqx_data).flatten() 
    212         dqy = numpy.outer(dr,self.dqy_data).flatten() 
    213  
    214         qx = self.qx_data.repeat(n_bins).reshape(len_data,\ 
    215                                              n_bins).transpose().flatten() 
    216         qy = self.qy_data.repeat(n_bins).reshape(len_data,\ 
    217                                              n_bins).transpose().flatten() 
    218  
    219         # The polar needs rotation by -q_phi 
    220         if self.coords == 'polar': 
    221             q_r = numpy.sqrt(qx * qx + qy * qy) 
    222             qx_res = ((dqx*numpy.cos(dphi) + q_r) * numpy.cos(-q_phi) +\ 
    223                            dqy*numpy.sin(dphi) * numpy.sin(-q_phi)) 
    224             qy_res = (-(dqx*numpy.cos(dphi) + q_r) * numpy.sin(-q_phi) +\ 
    225                            dqy*numpy.sin(dphi) * numpy.cos(-q_phi)) 
     143        # data length in the range of self.index 
     144        len_data = len(self.qx_data) 
     145        len_datay = len(self.qy_data) 
     146 
     147        if self._engine == 'c' and self.coords == 'polar': 
     148            try: 
     149                import sans_extension.smearer2d_helper as smearer2dc 
     150                smearc = smearer2dc.new_Smearer_helper(self.qx_data, self.qy_data, 
     151                                              self.dqx_data, self.dqy_data, 
     152                                              self.limit, nr, nphi, int(len_data)) 
     153                weight_res = numpy.zeros(nr * nphi ) 
     154                qx_res = numpy.zeros(nr * nphi * int(len_data)) 
     155                qy_res = numpy.zeros(nr * nphi * int(len_data)) 
     156                smearer2dc.smearer2d_helper(smearc,weight_res, qx_res, qy_res) 
     157            except: 
     158                raise  
    226159        else: 
    227             qx_res = qx +  dqx*numpy.cos(dphi) 
    228             qy_res = qy +  dqy*numpy.sin(dphi) 
    229  
     160            # Mean values of dqr at each bins ,starting from the half of bin size 
     161            r = bin_size / 2.0 + numpy.arange(nr) * bin_size 
     162            # mean values of qphi at each bines 
     163            phi = numpy.arange(nphi) 
     164            dphi = phi * 2.0 * math.pi / nphi 
     165            dphi = dphi.repeat(nr) 
     166     
     167            ## Transform to polar coordinate,  
     168            #  and set dphi at each data points ; 1d array 
     169            dphi = dphi.repeat(len_data) 
     170            q_phi = self.qy_data / self.qx_data 
     171             
     172            # Starting angle is different between polar and cartesian coordinates. 
     173            #if self.coords != 'polar': 
     174            #    dphi += numpy.arctan( q_phi * self.dqx_data/ \ 
     175            #                     self.dqy_data).repeat(n_bins).reshape(len_data,\ 
     176            #                                        n_bins).transpose().flatten() 
     177     
     178            # The angle (phi) of the original q point 
     179            q_phi = numpy.arctan(q_phi).repeat(n_bins).reshape(len_data,\ 
     180                                                    n_bins).transpose().flatten() 
     181            ## Find Gaussian weight for each dq bins: The weight depends only  
     182            #  on r-direction (The integration may not need) 
     183            weight_res = numpy.exp(-0.5 * ((r - bin_size / 2.0) * \ 
     184                                        (r - bin_size / 2.0)))- \ 
     185                                        numpy.exp(-0.5 * ((r + bin_size / 2.0 ) *\ 
     186                                        (r + bin_size / 2.0))) 
     187            # No needs of normalization here. 
     188            #weight_res /= numpy.sum(weight_res) 
     189            weight_res = weight_res.repeat(nphi).reshape(nr, nphi) 
     190     
     191            weight_res = weight_res.transpose().flatten() 
     192             
     193            ## Set dr for all dq bins for averaging 
     194            dr = r.repeat(nphi).reshape(nr,nphi).transpose().flatten() 
     195            ## Set dqr for all data points 
     196            dqx = numpy.outer(dr,self.dqx_data).flatten() 
     197            dqy = numpy.outer(dr,self.dqy_data).flatten() 
     198     
     199            qx = self.qx_data.repeat(n_bins).reshape(len_data,\ 
     200                                                 n_bins).transpose().flatten() 
     201            qy = self.qy_data.repeat(n_bins).reshape(len_data,\ 
     202                                                 n_bins).transpose().flatten() 
     203     
     204            # The polar needs rotation by -q_phi 
     205            if self.coords == 'polar': 
     206                q_r = numpy.sqrt(qx * qx + qy * qy) 
     207                qx_res = ((dqx*numpy.cos(dphi) + q_r) * numpy.cos(-q_phi) +\ 
     208                               dqy*numpy.sin(dphi) * numpy.sin(-q_phi)) 
     209                qy_res = (-(dqx*numpy.cos(dphi) + q_r) * numpy.sin(-q_phi) +\ 
     210                               dqy*numpy.sin(dphi) * numpy.cos(-q_phi)) 
     211            else: 
     212                qx_res = qx +  dqx*numpy.cos(dphi) 
     213                qy_res = qy +  dqy*numpy.sin(dphi) 
     214             
    230215        ## Evaluate all points 
    231216        val = self.model.evalDistribution([qx_res, qy_res])  
    232  
    233217        ## Reshape into 2d array to use numpy weighted averaging 
    234218        value_res= val.reshape(n_bins,len(self.qx_data)) 
    235  
    236219        ## Averaging with Gaussian weighting: normalization included. 
    237220        value =numpy.average(value_res,axis=0, weights=weight_res) 
    238  
    239221        ## Return the smeared values in the range of self.index 
    240222        return value 
Note: See TracChangeset for help on using the changeset viewer.