Changeset d4bf55e9 in sasview for sansmodels/src
- Timestamp:
- Mar 10, 2011 11:41:51 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:
- ae83ad3
- Parents:
- 510e7ad
- Location:
- sansmodels/src/sans/models
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
sansmodels/src/sans/models/LineModel.py
r988130c6 rd4bf55e9 6 6 from sans.models.BaseComponent import BaseComponent 7 7 import math 8 import numpy 8 9 9 10 … … 70 71 else: 71 72 return self._line(x) 73 74 def evalDistribution(self, qdist): 75 """ 76 Evaluate a distribution of q-values. 77 78 * For 1D, a numpy array is expected as input: 79 80 evalDistribution(q) 81 82 where q is a numpy array. 83 84 85 * For 2D, a list of numpy arrays are expected: [qx_prime,qy_prime], 86 where 1D arrays, 87 88 :param qdist: ndarray of scalar q-values or list [qx,qy] 89 where qx,qy are 1D ndarrays 90 91 """ 92 if qdist.__class__.__name__ == 'list': 93 # Check whether we have a list of ndarrays [qx,qy] 94 if len(qdist)!=2 or \ 95 qdist[0].__class__.__name__ != 'ndarray' or \ 96 qdist[1].__class__.__name__ != 'ndarray': 97 raise RuntimeError, "evalDistribution expects a list of 2 ndarrays" 98 99 # Extract qx and qy for code clarity 100 qx = qdist[0] 101 qy = qdist[1] 102 #For 2D, Z = A + B * Y, 103 # so that it keeps its linearity in y-direction. 104 # calculate q_r component for 2D isotropic 105 q = qy 106 # vectorize the model function runXY 107 v_model = numpy.vectorize(self.runXY,otypes=[float]) 108 # calculate the scattering 109 iq_array = v_model(q) 110 111 return iq_array 112 113 elif qdist.__class__.__name__ == 'ndarray': 114 # We have a simple 1D distribution of q-values 115 v_model = numpy.vectorize(self.runXY,otypes=[float]) 116 iq_array = v_model(qdist) 117 118 return iq_array 119 120 else: 121 mesg = "evalDistribution is expecting an ndarray of scalar q-values" 122 mesg += " or a list [qx,qy] where qx,qy are 2D ndarrays." 123 raise RuntimeError, mesg 124 125 72 126 73 127 -
sansmodels/src/sans/models/smearing_2d.py
r04eb1a4 rd4bf55e9 14 14 ## Limit of how many sigmas to be covered for the Gaussian smearing 15 15 # default: 2.5 to cover 98.7% of Gaussian 16 LIMIT = 2.516 LIMIT = 3.0 17 17 ## Defaults 18 18 R_BIN = {'Xhigh':10.0, 'High':5.0,'Med':5.0,'Low':3.0} … … 25 25 26 26 def __init__(self, data=None, model=None, index=None, 27 limit=LIMIT, accuracy='Low' ):27 limit=LIMIT, accuracy='Low', coords='polar'): 28 28 """ 29 29 Assumption: equally spaced bins in dq_r, dq_phi space. … … 34 34 :param nr: number of bins in dq_r-axis 35 35 :param nphi: number of bins in dq_phi-axis 36 :param coord: coordinates [string], 'polar' or 'cartesian' 36 37 """ 37 38 ## data … … 48 49 self.limit = limit 49 50 self.index = index 51 self.coords = coords 50 52 self.smearer = True 51 53 … … 61 63 self.qx_data = self.data.qx_data[self.index] 62 64 self.qy_data = self.data.qy_data[self.index] 65 self.q_data = self.data.q_data[self.index] 66 # Here dqx and dqy mean dq_parr and dq_perp 63 67 self.dqx_data = self.data.dqx_data[self.index] 64 68 self.dqy_data = self.data.dqy_data[self.index] … … 113 117 def get_value(self): 114 118 """ 115 Over sampling of r_nbins times phi_nbins, calculate Gaussian weights, then find smeared intensity 119 Over sampling of r_nbins times phi_nbins, calculate Gaussian weights, 120 then find smeared intensity 116 121 For the default values, this is equivalent (but by using numpy array 117 122 the speed optimized by a factor of ten)to the following: :: 118 123 119 124 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)) 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)) 136 148 137 149 Then compute I(qx_res,qy_res) and do weighted averaging. … … 145 157 numpy.all(numpy.fabs(self.dqy_data <= 1.1e-10)): 146 158 self.smearer = False 159 147 160 if self.smearer == False: 148 return self.model.evalDistribution([self.qx_data, self.qy_data])161 return self.model.evalDistribution([self.qx_data, self.qy_data]) 149 162 150 163 nr = self.nr[self.accuracy] … … 156 169 157 170 # 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 171 bin_size = self.limit / nr 172 # Total number of bins = # of bins 173 # in dq_r-direction times # of bins in dq_phi-direction 160 174 n_bins = nr * nphi 161 175 # Mean values of dqr at each bins ,starting from the half of bin size 162 r = bin_size /2.0+numpy.arange(nr)*bin_size176 r = bin_size / 2.0 + numpy.arange(nr) * bin_size 163 177 # mean values of qphi at each bines 164 178 phi = numpy.arange(nphi) 165 dphi = phi *2.0*math.pi/nphi179 dphi = phi * 2.0 * math.pi / nphi 166 180 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() 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 weight_res /= numpy.sum(weight_res) 203 weight_res = weight_res.repeat(nphi).reshape(nr, nphi) 204 205 weight_res = weight_res.transpose().flatten() 172 206 173 207 ## Set dr for all dq bins for averaging … … 176 210 dqx = numpy.outer(dr,self.dqx_data).flatten() 177 211 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 212 213 qx = self.qx_data.repeat(n_bins).reshape(len_data,\ 214 n_bins).transpose().flatten() 215 qy = self.qy_data.repeat(n_bins).reshape(len_data,\ 216 n_bins).transpose().flatten() 217 218 # The polar needs rotation by -q_phi 219 if self.coords == 'polar': 220 qx_res = qx + (dqx*numpy.cos(dphi) * numpy.cos(-q_phi) +\ 221 dqy*numpy.sin(dphi) * numpy.sin(-q_phi)) 222 qy_res = qy + (-dqx*numpy.cos(dphi) * numpy.sin(-q_phi) +\ 223 dqy*numpy.sin(dphi) * numpy.cos(-q_phi)) 224 else: 225 qx_res = qx + dqx*numpy.cos(dphi) 226 qy_res = qx + dqy*numpy.sin(dphi) 227 186 228 ## Evaluate all points 187 val = self.model.evalDistribution([qx_res, qy_res])229 val = self.model.evalDistribution([qx_res, qy_res]) 188 230 189 231 ## Reshape into 2d array to use numpy weighted averaging … … 191 233 192 234 ## Averaging with Gaussian weighting: normalization included. 193 value =numpy.average(value_res,axis=0, weights=weight_res)235 value =numpy.average(value_res,axis=0, weights=weight_res) 194 236 195 237 ## Return the smeared values in the range of self.index … … 199 241 ## Test w/ 2D linear function 200 242 x = 0.001*numpy.arange(1,11) 201 dx = numpy.ones(len(x))*0.00 1243 dx = numpy.ones(len(x))*0.0003 202 244 y = 0.001*numpy.arange(1,11) 203 245 dy = numpy.ones(len(x))*0.001 … … 214 256 out.dqx_data = dx 215 257 out.dqy_data = dy 258 out.q_data = numpy.sqrt(dx * dx + dy * dy) 216 259 index = numpy.ones(len(x), dtype = bool) 217 260 out.mask = index … … 225 268 ## All data are ones, so the smeared should also be ones. 226 269 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." 270 print " 2D linear function, I = 0 + 1*qy" 271 text = " Gaussian weighted averaging on a 2D linear function will " 272 text += "provides the results same as without the averaging." 273 print text 229 274 print "qx_data", "qy_data", "I_nonsmear", "I_smeared" 230 275 for ind in range(len(value)): 231 276 print x[ind],y[ind],model.evalDistribution([x,y])[ind], value[ind] 232 277 278 """ 279 for i in range(len(qx_res)/(128*128)): 280 k = i * 128*128 +64 281 282 print qx_res[k]-qqx[k], qy_res[k]-qqy[k] 283 print qqx[64],qqy[64] 284 """ 233 285 """ 234 286 if __name__ == '__main__':
Note: See TracChangeset
for help on using the changeset viewer.