Changeset 87615a48 in sasview for sansmodels/src/sans
- Timestamp:
- Jun 9, 2011 10:46:26 AM (14 years ago)
- 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
- Location:
- sansmodels/src/sans/models
- Files:
-
- 3 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sansmodels/src/sans/models/smearing_2d.py
r6e8b436 r87615a48 10 10 import numpy 11 11 import math 12 12 13 ## Singular point 13 14 SIGMA_ZERO = 1.0e-010 … … 16 17 LIMIT = 3.0 17 18 ## 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}19 R_BIN = {'Xhigh':10, 'High':5,'Med':5,'Low':3} 20 PHI_BIN ={'Xhigh':20,'High':12,'Med':6,'Low':4} 20 21 21 22 class Smearer2D: … … 25 26 26 27 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'): 28 29 """ 29 30 Assumption: equally spaced bins in dq_r, dq_phi space. … … 35 36 :param nphi: number of bins in dq_phi-axis 36 37 :param coord: coordinates [string], 'polar' or 'cartesian' 38 :param engine: engine name [string]; 'c' or 'numpy' 37 39 """ 38 40 ## data … … 51 53 self.coords = coords 52 54 self.smearer = True 55 self._engine = engine 53 56 54 57 … … 119 122 Over sampling of r_nbins times phi_nbins, calculate Gaussian weights, 120 123 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 """ 152 125 valid = self.get_data() 153 126 if valid == None: … … 163 136 nr = self.nr[self.accuracy] 164 137 nphi = self.nphi[self.accuracy] 165 166 # data length in the range of self.index167 len_data = len(self.qx_data)168 len_datay = len(self.qy_data)169 170 138 # Number of bins in the dqr direction (polar coordinate of dqx and dqy) 171 139 bin_size = self.limit / nr … … 173 141 # in dq_r-direction times # of bins in dq_phi-direction 174 142 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 226 159 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 230 215 ## Evaluate all points 231 216 val = self.model.evalDistribution([qx_res, qy_res]) 232 233 217 ## Reshape into 2d array to use numpy weighted averaging 234 218 value_res= val.reshape(n_bins,len(self.qx_data)) 235 236 219 ## Averaging with Gaussian weighting: normalization included. 237 220 value =numpy.average(value_res,axis=0, weights=weight_res) 238 239 221 ## Return the smeared values in the range of self.index 240 222 return value
Note: See TracChangeset
for help on using the changeset viewer.