source: sasview/sansmodels/src/sans/models/smearing_2d.py @ 9f391af

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 9f391af was 04eb1a4, checked in by Jae Cho <jhjcho@…>, 14 years ago

found and removed unused import in smear

  • Property mode set to 100644
File size: 9.9 KB
RevLine 
[642b259]1#####################################################################
2#This software was developed by the University of Tennessee as part of the
3#Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
4#project funded by the US National Science Foundation.
5#See the license text in license.txt
6#copyright 2008, University of Tennessee
7######################################################################
8
9## TODO: Need test,and check Gaussian averaging
[04eb1a4]10import numpy
11import math
[642b259]12## Singular point
13SIGMA_ZERO = 1.0e-010
14## Limit of how many sigmas to be covered for the Gaussian smearing
15# default: 2.5 to cover 98.7% of Gaussian
16LIMIT = 2.5
17## Defaults
18R_BIN = {'Xhigh':10.0, 'High':5.0,'Med':5.0,'Low':3.0}
19PHI_BIN ={'Xhigh':20.0,'High':12.0,'Med':6.0,'Low':4.0}   
20
21class Smearer2D:
22    """
23    Gaussian Q smearing class for SANS 2d data
24    """
25     
26    def __init__(self, data=None, model=None, index=None, 
27                 limit=LIMIT, accuracy='Low'):
28        """
29        Assumption: equally spaced bins in dq_r, dq_phi space.
30       
31        :param data: 2d data used to set the smearing parameters
32        :param model: model function
33        :param index: 1d array with len(data) to define the range of the calculation: elements are given as True or False
34        :param nr: number of bins in dq_r-axis
35        :param nphi: number of bins in dq_phi-axis
36        """
37        ## data
38        self.data = data
39        ## model
40        self.model = model
41        ## Accuracy: Higher stands for more sampling points in both directions of r and phi.
42        self.accuracy = accuracy
43        ## number of bins in r axis for over-sampling
44        self.nr = R_BIN
45        ## number of bins in phi axis for over-sampling
46        self.nphi = PHI_BIN
47        ## maximum nsigmas
48        self.limit = limit
49        self.index = index
50        self.smearer = True
51       
52       
53    def get_data(self):   
54        """
55        get qx_data, qy_data, dqx_data,dqy_data,and calculate phi_data=arctan(qx_data/qy_data)
56        """
57        if self.data == None or self.data.__class__.__name__ == 'Data1D':
58            return None
59        if self.data.dqx_data == None or self.data.dqy_data == None:
60            return None
61        self.qx_data = self.data.qx_data[self.index]
62        self.qy_data = self.data.qy_data[self.index]
63        self.dqx_data = self.data.dqx_data[self.index]
64        self.dqy_data = self.data.dqy_data[self.index]
65        self.phi_data = numpy.arctan(self.qx_data/self.qy_data)
66        ## Remove singular points if exists
67        self.dqx_data[self.dqx_data<SIGMA_ZERO]=SIGMA_ZERO
68        self.dqy_data[self.dqy_data<SIGMA_ZERO]=SIGMA_ZERO
69        return True
70   
71    def set_accuracy(self, accuracy='Low'):   
72        """
73        Set accuracy.
74       
75        :param accuracy:  string
76        """
77        self.accuracy = accuracy
78
79    def set_smearer(self, smearer=True):
80        """
81        Set whether or not smearer will be used
82       
83        :param smearer: smear object
84       
85        """
86        self.smearer = smearer
87       
88    def set_data(self, data=None):   
89        """
90        Set data.
91       
92        :param data: DataLoader.Data_info type
93        """
94        self.data = data
95 
96           
97    def set_model(self, model=None):   
98        """
99        Set model.
100       
101        :param model: sans.models instance
102        """
103        self.model = model 
104           
105    def set_index(self, index=None):   
106        """
107        Set index.
108       
109        :param index: 1d arrays
110        """
111        self.index = index       
112   
113    def get_value(self):
114        """
115        Over sampling of r_nbins times phi_nbins, calculate Gaussian weights, then find smeared intensity
116        For the default values, this is equivalent (but by using numpy array
117        the speed optimized by a factor of ten)to the following: ::
118       
119       
120            Remove the singular points if exists
121            self.dqx_data[self.dqx_data==0]=SIGMA_ZERO
122            self.dqy_data[self.dqy_data==0]=SIGMA_ZERO
123           
124            for phi in range(0,4):
125                for r in range(0,5):
126                    n = (phi)*5+(r)
127                    r = r+0.25
128                    dphi = phi*2.0*math.pi/4.0 + numpy.arctan(self.qy_data[index_model]/self.dqy_data[index_model]/self.qx_data[index_model]*/self.dqx_data[index_model])
129                    dq = r*sqrt( self.dqx_data[index_model]*self.dqx_data[index_model] \
130                        + self.dqy_data[index_model]*self.dqy_data[index_model] )
131                    #integrant of exp(-0.5*r*r) r dr at each bins : The integration may not need.
132                    weight_res[n] = e^{(-0.5*((r-0.25)*(r-0.25)))}- e^{(-0.5*((r-0.25)*(r-0.25)))}
133                    #if phi != 0 and r != 0:
134                    qx_res = numpy.append(qx_res,self.qx_data[index_model]+ dq * cos(dphi))
135                    qy_res = numpy.append(qy_res,self.qy_data[index_model]+ dq * sin(dphi))
136                   
137        Then compute I(qx_res,qy_res) and do weighted averaging.
138       
139        """
140        valid = self.get_data()
141        if valid == None:
142            return valid
[5a0d01b3]143        # all zero values of dq
[836a762]144        if numpy.all(numpy.fabs(self.dqx_data <= 1.1e-10)) and \
145                        numpy.all(numpy.fabs(self.dqy_data <= 1.1e-10)):
[5a0d01b3]146            self.smearer = False
[642b259]147        if self.smearer == False:
148            return self.model.evalDistribution([self.qx_data,self.qy_data]) 
[04eb1a4]149
[642b259]150        nr = self.nr[self.accuracy]
151        nphi = self.nphi[self.accuracy]
152
153        # data length in the range of self.index
154        len_data = len(self.qx_data)
155        len_datay = len(self.qy_data)
156
157        # Number of bins in the dqr direction (polar coordinate of dqx and dqy)
158        bin_size = self.limit/nr
159        # Total number of bins = # of bins in dq_r-direction times # of bins in dq_phi-direction
160        n_bins = nr * nphi
161        # Mean values of dqr at each bins ,starting from the half of bin size
162        r = bin_size/2.0+numpy.arange(nr)*bin_size
163        # mean values of qphi at each bines
164        phi = numpy.arange(nphi)
165        dphi = phi*2.0*math.pi/nphi
166        dphi = dphi.repeat(nr)
167        ## Transform to polar coordinate, and set dphi at each data points ; 1d array
168        dphi = dphi.repeat(len_data)+numpy.arctan(self.qy_data*self.dqx_data/self.qx_data/self.dqy_data).repeat(n_bins).reshape(len_data,n_bins).transpose().flatten()
169        ## Find Gaussian weight for each dq bins: The weight depends only on r-direction (The integration may not need)
170        weight_res = numpy.exp(-0.5*((r-bin_size/2.0)*(r-bin_size/2.0)))-numpy.exp(-0.5*((r+bin_size/2.0)*(r+bin_size/2.0)))
171        weight_res = weight_res.repeat(nphi).reshape(nr,nphi).transpose().flatten()
172       
173        ## Set dr for all dq bins for averaging
174        dr = r.repeat(nphi).reshape(nr,nphi).transpose().flatten()
175        ## Set dqr for all data points
176        dqx = numpy.outer(dr,self.dqx_data).flatten()
177        dqy = numpy.outer(dr,self.dqy_data).flatten()
178        qx = self.qx_data.repeat(n_bins).reshape(len_data,n_bins).transpose().flatten()
179        qy = self.qy_data.repeat(n_bins).reshape(len_data,n_bins).transpose().flatten()
180
181       
182        ## Over-sampled qx_data and qy_data.
183        qx_res = qx+ dqx*numpy.cos(dphi)
184        qy_res = qy+ dqy*numpy.sin(dphi)
185       
186        ## Evaluate all points
187        val = self.model.evalDistribution([qx_res,qy_res]) 
188
189        ## Reshape into 2d array to use numpy weighted averaging
190        value_res= val.reshape(n_bins,len(self.qx_data))
191
192        ## Averaging with Gaussian weighting: normalization included.
193        value =numpy.average(value_res,axis=0,weights=weight_res)
194
195        ## Return the smeared values in the range of self.index
196        return value
197   
198if __name__ == '__main__':
199    ## Test w/ 2D linear function
200    x = 0.001*numpy.arange(1,11)
201    dx = numpy.ones(len(x))*0.001
202    y = 0.001*numpy.arange(1,11)
203    dy = numpy.ones(len(x))*0.001
204    z = numpy.ones(10)
205    dz = numpy.sqrt(z)
206   
207    from DataLoader import Data2D
208    #for i in range(10): print i, 0.001 + i*0.008/9.0
209    #for i in range(100): print i, int(math.floor( (i/ (100/9.0)) ))
210    out = Data2D()
211    out.data = z
212    out.qx_data = x
213    out.qy_data = y
214    out.dqx_data = dx
215    out.dqy_data = dy
216    index = numpy.ones(len(x), dtype = bool)
217    out.mask = index
218    from sans.models.LineModel import LineModel
219    model = LineModel()
220    model.setParam("A", 0)
221
222    smear = Smearer2D(out,model,index)
223    #smear.set_accuracy('Xhigh')
224    value = smear.get_value()
225    ## All data are ones, so the smeared should also be ones.
226    print "Data length =",len(value)
227    print " 2D linear function, I = 0 + 1*qx*qy"
228    print " Gaussian weighted averaging on a 2D linear function will provides the results same as without the averaging."
229    print "qx_data", "qy_data", "I_nonsmear", "I_smeared"
230    for ind in range(len(value)):
231        print x[ind],y[ind],model.evalDistribution([x,y])[ind], value[ind]
232 
233"""   
234if __name__ == '__main__':
235    ## Another Test w/ constant function
236    x = 0.001*numpy.arange(1,11)
237    dx = numpy.ones(len(x))*0.001
238    y = 0.001*numpy.arange(1,11)
239    dy = numpy.ones(len(x))*0.001
240    z = numpy.ones(10)
241    dz = numpy.sqrt(z)
242   
243    from DataLoader import Data2D
244    #for i in range(10): print i, 0.001 + i*0.008/9.0
245    #for i in range(100): print i, int(math.floor( (i/ (100/9.0)) ))
246    out = Data2D()
247    out.data = z
248    out.qx_data = x
249    out.qy_data = y
250    out.dqx_data = dx
251    out.dqy_data = dy
252    index = numpy.ones(len(x), dtype = bool)
253    out.mask = index
254    from sans.models.Constant import Constant
255    model = Constant()
256
257    value = Smearer2D(out,model,index).get_value()
258    ## All data are ones, so the smeared values should also be ones.
259    print "Data length =",len(value), ", Data=",value
260"""   
Note: See TracBrowser for help on using the repository browser.