Changeset f867cd9 in sasview for DataLoader
- Timestamp:
- Dec 17, 2010 5:26:52 PM (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:
- 7342634
- Parents:
- 0d8c8d7
- Location:
- DataLoader
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
DataLoader/extensions/smearer.cpp
r65883cf rf867cd9 211 211 212 212 // Compute the fraction of the Gaussian contributing 213 // to the q bin between q_min and q_max214 double value = erf( (q_ max-q_j)/(sqrt(2.0)*width[j]) );215 value -= erf( (q_ min-q_j)/(sqrt(2.0)*width[j]) );213 // to the q_j bin between q_jmin and q_jmax 214 double value = erf( (q_jmax-q)/(sqrt(2.0)*width[i]) ); 215 value -= erf( (q_jmin-q)/(sqrt(2.0)*width[i]) ); 216 216 (*weights)[i*nbins+j] += value; 217 217 } … … 273 273 274 274 for(int i=first_bin; i<=last_bin; i++){ 275 // Skip if weight is less than 1e-04(this value is much smaller than 276 // the weight at the 3*sigma distance 277 // Will speed up a little bit... 278 if ((*weights)[q_i*nbins+i] < 1.0e-004){ 279 continue; 280 } 275 281 sum += iq_in[i] * (*weights)[q_i*nbins+i]; 276 282 counts += (*weights)[q_i*nbins+i]; … … 279 285 // Normalize counts 280 286 iq_out[q_i] = (counts>0.0) ? sum/counts : 0; 287 //printf("\n iii=%g,%g ",iq_out[q_i], q_i); 281 288 } 282 289 } -
DataLoader/qsmearing.py
ra7a5886 rf867cd9 8 8 ###################################################################### 9 9 import numpy 10 #import math10 import math 11 11 import logging 12 12 import sys … … 14 14 from DataLoader.smearing_2d import Smearer2D 15 15 16 def smear_selection(data1D ):16 def smear_selection(data1D, model = None): 17 17 """ 18 18 Creates the right type of smearer according … … 30 30 31 31 :param data1D: Data1D object 32 :param model: sans.model instance 32 33 """ 33 34 # Sanity check. If we are not dealing with a SANS Data1D … … 55 56 # If we found resolution smearing data, return a QSmearer 56 57 if _found_resolution == True: 57 return QSmearer(data1D )58 return QSmearer(data1D, model) 58 59 59 60 # Look for slit smearing data … … 86 87 def __init__(self): 87 88 self.nbins = 0 89 self.nbins_low = 0 90 self.nbins_high = 0 88 91 self._weights = None 89 92 ## Internal flag to keep track of C++ smearer initialization 90 93 self._init_complete = False 91 94 self._smearer = None 95 self.model = None 92 96 93 97 def __deepcopy__(self, memo={}): … … 121 125 if q_max == None: 122 126 q_max = self.max 127 123 128 _qmin_unsmeared, _qmax_unsmeared = self.get_unsmeared_range(q_min, 124 129 q_max) … … 126 131 _last_bin = None 127 132 128 step = (self.max - self.min) / (self.nbins - 1.0) 133 #step = (self.max - self.min) / (self.nbins - 1.0) 134 # Find the first and last bin number in all extrapolated and real data 129 135 try: 130 136 for i in range(self.nbins): … … 140 146 msg += " error getting range\n %s" % sys.exc_value 141 147 raise RuntimeError, msg 142 148 149 # Find the first and last bin number only in the real data 150 _first_bin, _last_bin = self._get_unextrapolated_bin( \ 151 _first_bin, _last_bin) 152 143 153 return _first_bin, _last_bin 144 154 145 def __call__(self, iq_in, first_bin =0, last_bin=None):155 def __call__(self, iq_in, first_bin = 0, last_bin = None): 146 156 """ 147 157 Perform smearing … … 151 161 if not self._init_complete: 152 162 self._initialize_smearer() 153 154 # Get the max value for the last bin 163 155 164 if last_bin is None or last_bin >= len(iq_in): 156 165 last_bin = len(iq_in) - 1 … … 159 168 first_bin = 0 160 169 170 # With a model given, compute I for the extrapolated points and append 171 # to the iq_in 172 #iq_in_temp = iq_in 173 if self.model != None: 174 temp_first, temp_last = self._get_extrapolated_bin( \ 175 first_bin, last_bin) 176 iq_in_low = self.model.evalDistribution( \ 177 self.qvalues[0:self.nbins_low]) 178 iq_in_high = self.model.evalDistribution( \ 179 self.qvalues[(len(self.qvalues) - \ 180 self.nbins_high - 1): -1]) 181 if self.nbins_low > 0: 182 iq_in_temp = numpy.append(iq_in_low, iq_in) 183 if self.nbins_high > 0: 184 iq_in_temp = numpy.append(iq_in_temp, iq_in_high) 185 else: 186 temp_first = first_bin 187 temp_last = last_bin 188 iq_in_temp = iq_in 161 189 # Sanity check 162 if len(iq_in ) != self.nbins:190 if len(iq_in_temp) != self.nbins: 163 191 msg = "Invalid I(q) vector: inconsistent array " 164 msg += " length %d != %s" % (len(iq_in ), str(self.nbins))192 msg += " length %d != %s" % (len(iq_in_temp), str(self.nbins)) 165 193 raise RuntimeError, msg 166 194 167 195 # Storage for smeared I(q) 168 196 iq_out = numpy.zeros(self.nbins) 169 smear_output = smearer.smear(self._smearer, iq_in, iq_out, 170 first_bin, last_bin) 197 198 smear_output = smearer.smear(self._smearer, iq_in_temp, iq_out, 199 #0, self.nbins - 1) 200 temp_first, temp_last) 201 #first_bin, last_bin) 171 202 if smear_output < 0: 172 203 msg = "_BaseSmearer: could not smear, code = %g" % smear_output 173 204 raise RuntimeError, msg 174 return iq_out 205 206 207 temp_first += self.nbins_low 208 temp_last = self.nbins - (self.nbins_high + 1) 209 210 return iq_out[temp_first: (temp_last + 1)] 175 211 176 212 def _initialize_smearer(self): … … 179 215 return NotImplemented 180 216 217 def set_model(self, model): 218 """ 219 Set model 220 """ 221 if model != None: 222 self.model = model 223 224 225 def _get_unextrapolated_bin(self, first_bin = 0, last_bin = 0): 226 """ 227 Get unextrapolated first bin and the last bin 228 229 : param first_bin: extrapolated first_bin 230 : param last_bin: extrapolated last_bin 231 232 : return fist_bin, last_bin: unextrapolated first and last bin 233 """ 234 # For first bin 235 if first_bin <= self.nbins_low: 236 first_bin = 0 237 else: 238 first_bin = first_bin - self.nbins_low 239 # For last bin 240 if last_bin >= (self.nbins - self.nbins_high): 241 last_bin = self.nbins - (self.nbins_high + self.nbins_low + 1) 242 elif last_bin >= self.nbins_low: 243 last_bin = last_bin - self.nbins_low 244 else: 245 last_bin = 0 246 return first_bin, last_bin 247 248 def _get_extrapolated_bin(self, first_bin = 0, last_bin = 0): 249 """ 250 Get extrapolated first bin and the last bin 251 252 : param first_bin: unextrapolated first_bin 253 : param last_bin: unextrapolated last_bin 254 255 : return first_bin, last_bin: extrapolated first and last bin 256 """ 257 # For the first bin 258 if first_bin > 0: 259 # In the case that doesn't need lower q extrapolation data 260 first_bin += self.nbins_low 261 else: 262 # In the case that needs low extrapolation data 263 first_bin = 0 264 # For last bin 265 if last_bin >= self.nbins - (self.nbins_high + self.nbins_low + 1): 266 # In the case that needs higher q extrapolation data 267 last_bin = self.nbins - 1 268 else: 269 # In the case that doesn't need higher q extrapolation data 270 last_bin += self.nbins_low 271 272 return first_bin, last_bin 273 181 274 class _SlitSmearer(_BaseSmearer): 182 275 """ … … 253 346 ## Slit width 254 347 self.width = 0 348 self.nbins_low = 0 349 self.nbins_high = 0 255 350 if data1D.dxw is not None and len(data1D.dxw) == len(data1D.x): 256 351 self.width = data1D.dxw[0] … … 342 437 Adaptor for Gaussian Q smearing class and SANS data 343 438 """ 344 def __init__(self, data1D ):439 def __init__(self, data1D, model = None): 345 440 """ 346 441 Assumption: equally spaced bins of increasing q-values. … … 350 445 # Initialization from parent class 351 446 super(QSmearer, self).__init__() 352 447 data1d_x = [] 448 self.nbins_low = 0 449 self.nbins_high = 0 450 self.model = model 353 451 ## Resolution 354 self.width = numpy.zeros(len(data1D.x))452 #self.width = numpy.zeros(len(data1D.x)) 355 453 if data1D.dx is not None and len(data1D.dx) == len(data1D.x): 356 454 self.width = data1D.dx 357 455 456 if self.model == None: 457 data1d_x = data1D.x 458 else: 459 self.nbins_low, self.nbins_high, self.width, data1d_x = \ 460 get_qextrapolate(self.width, data1D.x) 461 358 462 ## Number of Q bins 359 self.nbins = len(data1 D.x)463 self.nbins = len(data1d_x) 360 464 ## Minimum Q 361 self.min = min(data1 D.x)465 self.min = min(data1d_x) 362 466 ## Maximum 363 self.max = max(data1 D.x)467 self.max = max(data1d_x) 364 468 ## Q-values 365 self.qvalues = data1D.x 366 367 469 self.qvalues = data1d_x 470 471 472 def get_qextrapolate(width, data_x): 473 """ 474 Make fake data_x points extrapolated outside of the data_x points 475 476 : param width: array of std of q resolution 477 : param Data1D.x: Data1D.x array 478 479 : return new_width, data_x_ext: extrapolated width array and x array 480 481 : assumption1: data_x is ordered from lower q to higher q 482 : assumption2: len(data) = len(width) 483 : assumption3: the distance between the data points is more compact 484 than the size of width 485 : Todo1: Make sure that the assumptions are correct for Data1D 486 : Todo2: This fixes the edge problem in Qsmearer but still needs to make 487 smearer interface 488 """ 489 # Length of the width 490 length = len(width) 491 max_width = max(width) 492 # Find bin sizes 493 bin_size_low = math.fabs(data_x[1] - data_x[0]) 494 bin_size_high = math.fabs(data_x[length -1] - data_x[length -2]) 495 # Number of q points required below the 1st data point in order to extend 496 # them 3 times of the width (std) 497 nbins_low = math.ceil(3 * max_width / bin_size_low) 498 # Number of q points required above the last data point 499 nbins_high = math.ceil(3 * max_width / (bin_size_high)) 500 # Make null q points 501 extra_low = numpy.zeros(nbins_low) 502 extra_high = numpy.zeros(nbins_high) 503 # Give extrapolated values 504 ind = 0 505 qvalue = data_x[0] - bin_size_low 506 while(ind < nbins_low): 507 extra_low[nbins_low - (ind + 1)] = qvalue 508 qvalue -= bin_size_low 509 ind += 1 510 # Remove the points <= 0 511 extra_low = extra_low[extra_low > 0] 512 nbins_low = len(extra_low) 513 # Reset ind for another extrapolation 514 ind = 0 515 qvalue = data_x[length -1] + bin_size_high 516 while(ind < nbins_high): 517 extra_high[ind] = qvalue 518 qvalue += bin_size_high 519 ind += 1 520 # Make a new qx array 521 data_x_ext = numpy.append(extra_low, data_x) 522 data_x_ext = numpy.append(data_x_ext, extra_high) 523 # Redefine extra_low and high based on corrected nbins 524 # And note that it is not necessary for extra_width to be a non-zero 525 extra_low = numpy.zeros(nbins_low) 526 extra_high = numpy.zeros(nbins_high) 527 # Make new width array 528 new_width = numpy.append(extra_low, width) 529 new_width = numpy.append(new_width, extra_high) 530 531 return nbins_low, nbins_high, new_width, data_x_ext 532 368 533 if __name__ == '__main__': 369 534 x = 0.001 * numpy.arange(1, 11) -
DataLoader/test/utest_smearing.py
r5859862 rf867cd9 89 89 5.00093415, 4.01898292, 3.15008701, 2.55214921] 90 90 for i in range(len(input)): 91 self.assertAlmostEqual(answer[i], output[i], 5)91 self.assertAlmostEqual(answer[i], output[i], 4) 92 92 93 93
Note: See TracChangeset
for help on using the changeset viewer.