source: sasview/DataLoader/smearing_2d.py @ a378756

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 a378756 was f72333f, checked in by Jae Cho <jhjcho@…>, 15 years ago

Plugged in 2D smear: traditional over-sampling method

  • Property mode set to 100644
File size: 8.1 KB
Line 
1"""
2This software was developed by the University of Tennessee as part of the
3Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
4project funded by the US National Science Foundation.
5
6See the license text in license.txt
7
8copyright 2009, University of Tennessee
9"""
10## TODO: Need test,and check Gaussian averaging
11import numpy, math,time
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,limit=LIMIT,accuracy='Low'):
27        """
28            Assumption: equally spaced bins of increasing q-values.
29           
30            @param data: 2d data used to set the smearing parameters
31            @param model: model function
32            @param index: 1d array with len(data) to define the range of the calculation: elements are given as True or False
33            @param nr: number of bins in dq_r-axis
34            @param nphi: number of bins in dq_phi-axis
35        """
36        ## data
37        self.data = data
38        ## model
39        self.model = model
40        ## Accuracy: Higher stands for more sampling points in both directions of r and phi.
41        self.accuracy = accuracy
42        ## number of bins in r axis for over-sampling
43        self.nr = R_BIN
44        ## number of bins in phi axis for over-sampling
45        self.nphi = PHI_BIN
46        ## maximum nsigmas
47        self.limit = limit
48        self.index = index
49        self.smearer = True
50       
51       
52    def get_data(self):   
53        """
54            get qx_data, qy_data, dqx_data,dqy_data,and calculate phi_data=arctan(qx_data/qy_data)
55        """
56        if self.data == None or self.data.__class__.__name__ == 'Data1D':
57            return None
58        if self.data.dqx_data == None or self.data.dqy_data == None:
59            return None
60        self.qx_data = self.data.qx_data[self.index]
61        self.qy_data = self.data.qy_data[self.index]
62        self.dqx_data = self.data.dqx_data[self.index]
63        self.dqy_data = self.data.dqy_data[self.index]
64        self.phi_data = numpy.arctan(self.qx_data/self.qy_data)
65        ## Remove singular points if exists
66        self.dqx_data[self.dqx_data<SIGMA_ZERO]=SIGMA_ZERO
67        self.dqy_data[self.dqy_data<SIGMA_ZERO]=SIGMA_ZERO
68        return True
69   
70    def set_accuracy(self,accuracy='Low'):   
71        """
72            Set accuracy:  string
73        """
74        self.accuracy = accuracy
75
76    def set_smearer(self,smearer = True):
77        """
78            Set whether or not smearer will be used
79        """
80        self.smearer = smearer
81       
82    def set_data(self,data=None):   
83        """
84            Set data:  1d arrays
85        """
86        self.data = data
87 
88           
89    def set_model(self,model=None):   
90        """
91            Set model
92        """
93        self.model = model 
94           
95    def set_index(self,index=None):   
96        """
97            Set index: 1d arrays
98        """
99
100        self.index = index       
101   
102    def get_value(self):
103        """
104            Over sampling of r_nbins times phi_nbins, calculate Gaussian weights, then find semared intensity
105            # For the default vaues, this is equivalent (but speed optimized by a factor of ten)to the following:
106            =====================================================================================
107            ## Remove the singular points if exists
108            self.dqx_data[self.dqx_data==0]=SIGMA_ZERO
109            self.dqy_data[self.dqy_data==0]=SIGMA_ZERO
110            for phi in range(0,4):
111                for r in range(0,5):
112                    n = (phi)*5+(r)
113                    r = r+0.25
114                    dphi = phi*2.0*math.pi/4.0 + numpy.arctan(self.qy_data[index_model]/self.qx_data[index_model])
115                    dq = r*numpy.sqrt( self.dqx_data[index_model]*self.dqx_data[index_model] \
116                        + self.dqy_data[index_model]*self.dqy_data[index_model] )
117                    #integrant of r*math.exp(-0.5*r*r) dr at each bins
118                    weight_res[n] = math.exp(-0.5*((r-0.25)*(r-0.25)))-math.exp(-0.5*((r-0.25)*(r-0.25)))
119                    #if phi !=0 and r != 0:
120                    qx_res=numpy.append(qx_res,self.qx_data[index_model]+ dq*math.cos(dphi))
121                    qy_res=numpy.append(qy_res,self.qy_data[index_model]+ dq*math.sin(dphi))
122            =====================================================================================
123        """
124        valid = self.get_data()
125        if valid == None:
126            return valid
127        if self.smearer == False:
128            return self.model.evalDistribution([self.qx_data,self.qy_data]) 
129        st = time.time()
130        nr = self.nr[self.accuracy]
131        nphi = self.nphi[self.accuracy]
132
133        # data length in the range of self.index
134        len_data = len(self.qx_data)
135        len_datay = len(self.qy_data)
136
137        # Number of bins in the dqr direction (polar coordinate of dqx and dqy)
138        bin_size = self.limit/nr
139        # Total number of bins = # of bins in dq_r-direction times # of bins in dq_phi-direction
140        n_bins = nr * nphi
141        # Mean values of dqr at each bins ,starting from the half of bin size
142        r = bin_size/2.0+numpy.arange(nr)*bin_size
143        # mean values of qphi at each bines
144        phi = numpy.arange(nphi)
145        dphi = phi*2.0*math.pi/nphi
146        dphi = dphi.repeat(nr)
147        ## Transform to polar coordinate and set dphi at each data points ; 1d array
148        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()
149        ## Find Gaussian weight for each dq bins: The weight depends only on r-direction
150        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)))
151        weight_res = weight_res.repeat(nphi).reshape(nr,nphi).transpose().flatten()
152       
153        ## Set dr for all dq bins for averaging
154        dr = r.repeat(nphi).reshape(nr,nphi).transpose().flatten()
155        ## Set dqr for all data points
156        dqx = numpy.outer(dr,self.dqx_data).flatten()
157        dqy = numpy.outer(dr,self.dqy_data).flatten()
158        qx = self.qx_data.repeat(n_bins).reshape(len_data,n_bins).transpose().flatten()
159        qy = self.qy_data.repeat(n_bins).reshape(len_data,n_bins).transpose().flatten()
160
161       
162        ## Over-sampled qx_data and qy_data.
163        qx_res = qx+ dqx*numpy.cos(dphi)
164        qy_res = qy+ dqy*numpy.sin(dphi)
165       
166        ## Evaluate all points
167        val = self.model.evalDistribution([qx_res,qy_res]) 
168
169        ## Reshape into 2d array to use numpy weighted averaging
170        value_res= val.reshape(n_bins,len(self.qx_data))
171
172        ## Averaging with Gaussian weighting: normalization included.
173        value =numpy.average(value_res,axis=0,weights=weight_res)
174
175        ## Return the smeared values in the range of self.index
176        return value
177   
178   
179if __name__ == '__main__':
180    ## Test
181    x = 0.001*numpy.arange(1,11)
182    dx = numpy.ones(len(x))*0.001
183    y = 0.001*numpy.arange(1,11)
184    dy = numpy.ones(len(x))*0.001
185    z = numpy.ones(10)
186    dz = numpy.sqrt(z)
187   
188    from DataLoader import Data2D
189    #for i in range(10): print i, 0.001 + i*0.008/9.0
190    #for i in range(100): print i, int(math.floor( (i/ (100/9.0)) ))
191    out = Data2D()
192    out.data = z
193    out.qx_data = x
194    out.qy_data = y
195    out.dqx_data = dx
196    out.dqy_data = dy
197    index = numpy.ones(len(x), dtype = bool)
198    out.mask = index
199    from sans.models.Constant import Constant
200    model = Constant()
201
202    value = Smearer2D(out,model,index).get_value()
203    ## All data are ones, so the smeared should also be ones.
204    print "Data length =",len(value), ", Data=",value
205   
Note: See TracBrowser for help on using the repository browser.