- Timestamp:
- Mar 30, 2015 10:51:41 AM (10 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:
- edfc8ac
- Parents:
- d5419f7f
- Location:
- src/sas
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/models/qsmearing.py
r9f7fbd9 ra3f125f0 59 59 if _found_resolution == True: 60 60 return QSmearer(data1D, model) 61 #return pinhole_smear(data1D, model) 61 62 62 63 # Look for slit smearing data … … 81 82 # If we found slit smearing data, return a slit smearer 82 83 if _found_slit == True: 83 return PySlitSmearer(data1D, model) 84 #return SlitSmearer(data1D, model) 85 return slit_smear(data1D, model) 84 86 return None 85 87 … … 198 200 iq_in[len(iq_in) - 1] = iq_in_high[0] 199 201 # Append the extrapolated points to the data points 200 if self.nbins_low > 0: 202 if self.nbins_low > 0: 201 203 iq_in_temp = numpy.append(iq_in_low, iq_in) 202 204 if self.nbins_high > 0: … … 586 588 587 589 588 from .resolution import Slit1D 589 class PySlitSmearer(object): 590 def __init__(self, data1D, model = None): 590 from .resolution import Slit1D, Pinhole1D 591 class PySmear(object): 592 """ 593 Wrapper for pure python sasmodels resolution functions. 594 """ 595 def __init__(self, resolution, model): 591 596 self.model = model 592 593 q = data1D.x 594 width = data1D.dxw if data1D.dxw is not None else 0 595 height = data1D.dxl if data1D.dxl is not None else 0 596 # TODO: width and height seem to be reversed 597 self.resolution = Slit1D(q, height, width) 598 599 def __call__(self, iq_in, first_bin=0, last_bin=None): 600 if last_bin is None or last_bin >= len(iq_in): 601 last_bin = len(iq_in) - 1 597 self.resolution = resolution 598 self.offset = numpy.searchsorted(self.resolution.q_calc, self.resolution.q[0]) 599 600 def apply(self, iq_in, first_bin=0, last_bin=None): 601 """ 602 Apply the resolution function to the data. 603 604 Note that this is called with iq_in matching data.x, but with 605 iq_in[first_bin:last_bin] set to theory values for these bins, 606 and the remainder left undefined. The first_bin, last_bin values 607 should be those returned from get_bin_range. 608 609 The returned value is of the same length as iq_in, with the range 610 first_bin:last_bin set to the resolution smeared values. 611 """ 612 if last_bin is None: last_bin = len(iq_in) 613 start, end = first_bin + self.offset, last_bin + self.offset 602 614 q_calc = self.resolution.q_calc 603 615 iq_calc = numpy.empty_like(q_calc) 604 iq_calc[:first_bin] = 0 605 iq_calc[first_bin:last_bin+1] = iq_in 606 if last_bin < len(q_calc)-1: 607 iq_calc[last_bin:] = self.model.evalDistribution(q_calc[last_bin:]) 608 iq_out = self.resolution.apply(iq_calc) 609 return iq_out[first_bin:last_bin+1] 616 if start > 0: 617 iq_calc[:start] = self.model.evalDistribution(q_calc[:start]) 618 if end+1 < len(q_calc): 619 iq_calc[end+1:] = self.model.evalDistribution(q_calc[end+1:]) 620 iq_calc[start:end+1] = iq_in[first_bin:last_bin+1] 621 smeared = self.resolution.apply(iq_calc) 622 return smeared 623 __call__ = apply 610 624 611 625 def get_bin_range(self, q_min=None, q_max=None): 612 626 """ 613 614 :param q_min: minimum q-value to smear 615 :param q_max: maximum q-value to smear 616 617 """ 618 # assume the data values are sorted 619 first = numpy.searchsorted(self.resolution.q, q_min) 620 # assume that the resolution is much larger than the q range 621 last = len(self.resolution.q)-1 622 return first, last 627 For a given q_min, q_max, find the corresponding indices in the data. 628 629 Returns first, last. 630 631 Note that these are indexes into q from the data, not the q_calc 632 needed by the resolution function. Note also that these are the 633 indices, not the range limits. That is, the complete range will be 634 q[first:last+1]. 635 """ 636 q = self.resolution.q 637 first = numpy.searchsorted(q, q_min) 638 last = numpy.searchsorted(q, q_max) 639 return first, min(last,len(q)-1) 640 641 def slit_smear(data, model=None): 642 q = data.x 643 width = data.dxw if data.dxw is not None else 0 644 height = data.dxl if data.dxl is not None else 0 645 # TODO: width and height seem to be reversed 646 return PySmear(Slit1D(q, height, width), model) 647 648 def pinhole_smear(data, model=None): 649 q = data.x 650 width = data.dx if data.dx is not None else 0 651 return PySmear(Pinhole1D(q, width), model) -
src/sas/models/resolution.py
r9f7fbd9 ra3f125f0 56 56 be estimated from the *q* and *q_width*. 57 57 """ 58 def __init__(self, q, q_width, q_calc=None ):58 def __init__(self, q, q_width, q_calc=None, nsigma=3): 59 59 #*min_step* is the minimum point spacing to use when computing the 60 60 #underlying model. It should be on the order of … … 68 68 # default to Perfect1D if the pinhole geometry is not defined. 69 69 self.q, self.q_width = q, q_width 70 self.q_calc = pinhole_extend_q(q, q_width ) \70 self.q_calc = pinhole_extend_q(q, q_width, nsigma=nsigma) \ 71 71 if q_calc is None else np.sort(q_calc) 72 72 self.weight_matrix = pinhole_resolution(self.q_calc, … … 203 203 """ 204 204 q_min, q_max = np.min(q - nsigma*q_width), np.max(q + nsigma*q_width) 205 return geometric_extrapolation(q, q_min, q_max)205 return linear_extrapolation(q, q_min, q_max) 206 206 207 207 … … 267 267 """ 268 268 Extrapolate *q* out to [*q_min*, *q_max*] using the step size in *q* as 269 a guide. Extrapolation below uses stepsthe same size as the first270 interval. Extrapolation above uses stepsthe same size as the final269 a guide. Extrapolation below uses about the same size as the first 270 interval. Extrapolation above uses about the same size as the final 271 271 interval. 272 272 … … 276 276 if q_min < q[0]: 277 277 if q_min <= 0: q_min = q[0]/10 278 delta = q[1] - q[0]279 q_low = np. arange(q_min, q[0], delta)278 n_low = np.ceil((q[0]-q_min) / (q[1]-q[0])) if q[1]>q[0] else 15 279 q_low = np.linspace(q_min, q[0], n_low+1)[:-1] 280 280 else: 281 281 q_low = [] 282 282 if q_max > q[-1]: 283 delta = q[-1] - q[-2]284 q_high = np. arange(q[-1]+delta, q_max, delta)283 n_high = np.ceil((q_max-q[-1]) / (q[-1]-q[-2])) if q[-1]>q[-2] else 15 284 q_high = np.linspace(q[-1], q_max, n_high+1)[1:] 285 285 else: 286 286 q_high = [] … … 288 288 289 289 290 def geometric_extrapolation(q, q_min, q_max ):290 def geometric_extrapolation(q, q_min, q_max, points_per_decade=None): 291 291 r""" 292 292 Extrapolate *q* to [*q_min*, *q_max*] using geometric steps, with the … … 295 295 if *q_min* is zero or less then *q[0]/10* is used instead. 296 296 297 Starting at $q_1$ and stepping geometrically by $\Delta q$ 298 to $q_n$ in $n$ points gives a geometric average of: 297 *points_per_decade* sets the ratio between consecutive steps such 298 that there will be $n$ points used for every factor of 10 increase 299 in *q*. 300 301 If *points_per_decade* is not given, it will be estimated as follows. 302 Starting at $q_1$ and stepping geometrically by $\Delta q$ to $q_n$ 303 in $n$ points gives a geometric average of: 299 304 300 305 .. math:: … … 315 320 """ 316 321 q = np.sort(q) 317 delta_q = (len(q)-1)/(log(q[-1]) - log(q[0])) 322 if points_per_decade is None: 323 log_delta_q = (len(q) - 1) / (log(q[-1]) - log(q[0])) 324 else: 325 log_delta_q = log(10.) / points_per_decade 318 326 if q_min < q[0]: 319 327 if q_min < 0: q_min = q[0]/10 320 n_low = delta_q * (log(q[0])-log(q_min))328 n_low = log_delta_q * (log(q[0])-log(q_min)) 321 329 q_low = np.logspace(log10(q_min), log10(q[0]), np.ceil(n_low)+1)[:-1] 322 330 else: 323 331 q_low = [] 324 332 if q_max > q[-1]: 325 n_high = delta_q * (log(q_max)-log(q[-1]))333 n_high = log_delta_q * (log(q_max)-log(q[-1])) 326 334 q_high = np.logspace(log10(q[-1]), log10(q_max), np.ceil(n_high)+1)[1:] 327 335 else: … … 329 337 return np.concatenate([q_low, q, q_high]) 330 338 339 340 ############################################################################ 341 # unit tests 342 ############################################################################ 343 import unittest 344 345 346 def eval_form(q, form, pars): 347 from sasmodels import core 348 kernel = core.make_kernel(form, [q]) 349 theory = core.call_kernel(kernel, pars) 350 kernel.release() 351 return theory 352 353 354 def gaussian(q, q0, dq): 355 from numpy import exp, pi 356 return exp(-0.5*((q-q0)/dq)**2)/(sqrt(2*pi)*dq) 357 358 359 def romberg_slit_1d(q, delta_qv, form, pars): 360 """ 361 Romberg integration for slit resolution. 362 363 This is an adaptive integration technique. It is called with settings 364 that make it slow to evaluate but give it good accuracy. 365 """ 366 from scipy.integrate import romberg 367 368 if any(k not in form.info['defaults'] for k in pars.keys()): 369 keys = set(form.info['defaults'].keys()) 370 extra = set(pars.keys()) - keys 371 raise ValueError("bad parameters: [%s] not in [%s]"% 372 (", ".join(sorted(extra)), ", ".join(sorted(keys)))) 373 374 _fn = lambda u, q0: eval_form(sqrt(q0**2 + u**2), form, pars) 375 r = [romberg(_fn, 0, delta_qv[0], args=(qi,), 376 divmax=100, vec_func=True, tol=0, rtol=1e-8) 377 for qi in q] 378 # r should be [float, ...], but it is [array([float]), array([float]),...] 379 return np.asarray(r).flatten()/delta_qv[0] 380 381 382 def romberg_pinhole_1d(q, q_width, form, pars, nsigma=5): 383 """ 384 Romberg integration for pinhole resolution. 385 386 This is an adaptive integration technique. It is called with settings 387 that make it slow to evaluate but give it good accuracy. 388 """ 389 from scipy.integrate import romberg 390 391 if any(k not in form.info['defaults'] for k in pars.keys()): 392 keys = set(form.info['defaults'].keys()) 393 extra = set(pars.keys()) - keys 394 raise ValueError("bad parameters: [%s] not in [%s]"% 395 (", ".join(sorted(extra)), ", ".join(sorted(keys)))) 396 397 _fn = lambda q, q0, dq: eval_form(q, form, pars)*gaussian(q, q0, dq) 398 r = [romberg(_fn, max(qi-nsigma*dqi,1e-10*q[0]), qi+nsigma*dqi, args=(qi, dqi), 399 divmax=100, vec_func=True, tol=0, rtol=1e-8) 400 for qi,dqi in zip(q,q_width)] 401 return np.asarray(r).flatten() 402 403 404 class ResolutionTest(unittest.TestCase): 405 406 def setUp(self): 407 self.x = 0.001*np.arange(1, 11) 408 self.y = self.Iq(self.x) 409 410 def Iq(self, q): 411 "Linear function for resolution unit test" 412 return 12.0 - 1000.0*q 413 414 def test_perfect(self): 415 """ 416 Perfect resolution and no smearing. 417 """ 418 resolution = Perfect1D(self.x) 419 theory = self.Iq(resolution.q_calc) 420 output = resolution.apply(theory) 421 np.testing.assert_equal(output, self.y) 422 423 def test_slit_zero(self): 424 """ 425 Slit smearing with perfect resolution. 426 """ 427 resolution = Slit1D(self.x, width=0, height=0, q_calc=self.x) 428 theory = self.Iq(resolution.q_calc) 429 output = resolution.apply(theory) 430 np.testing.assert_equal(output, self.y) 431 432 @unittest.skip("not yet supported") 433 def test_slit_high(self): 434 """ 435 Slit smearing with height 0.005 436 """ 437 resolution = Slit1D(self.x, width=0, height=0.005, q_calc=self.x) 438 theory = self.Iq(resolution.q_calc) 439 output = resolution.apply(theory) 440 answer = [ 9.0618, 8.6402, 8.1187, 7.1392, 6.1528, 441 5.5555, 4.5584, 3.5606, 2.5623, 2.0000 ] 442 np.testing.assert_allclose(output, answer, atol=1e-4) 443 444 @unittest.skip("not yet supported") 445 def test_slit_both_high(self): 446 """ 447 Slit smearing with width < 100*height. 448 """ 449 q = np.logspace(-4, -1, 10) 450 resolution = Slit1D(q, width=0.2, height=np.inf) 451 theory = 1000*self.Iq(resolution.q_calc**4) 452 output = resolution.apply(theory) 453 answer = [ 8.85785, 8.43012, 7.92687, 6.94566, 6.03660, 454 5.40363, 4.40655, 3.40880, 2.41058, 2.00000 ] 455 np.testing.assert_allclose(output, answer, atol=1e-4) 456 457 @unittest.skip("not yet supported") 458 def test_slit_wide(self): 459 """ 460 Slit smearing with width 0.0002 461 """ 462 resolution = Slit1D(self.x, width=0.0002, height=0, q_calc=self.x) 463 theory = self.Iq(resolution.q_calc) 464 output = resolution.apply(theory) 465 answer = [ 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0 ] 466 np.testing.assert_allclose(output, answer, atol=1e-4) 467 468 @unittest.skip("not yet supported") 469 def test_slit_both_wide(self): 470 """ 471 Slit smearing with width > 100*height. 472 """ 473 resolution = Slit1D(self.x, width=0.0002, height=0.000001, 474 q_calc=self.x) 475 theory = self.Iq(resolution.q_calc) 476 output = resolution.apply(theory) 477 answer = [ 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0 ] 478 np.testing.assert_allclose(output, answer, atol=1e-4) 479 480 def test_pinhole_zero(self): 481 """ 482 Pinhole smearing with perfect resolution 483 """ 484 resolution = Pinhole1D(self.x, 0.0*self.x) 485 theory = self.Iq(resolution.q_calc) 486 output = resolution.apply(theory) 487 np.testing.assert_equal(output, self.y) 488 489 def test_pinhole(self): 490 """ 491 Pinhole smearing with dQ = 0.001 [Note: not dQ/Q = 0.001] 492 """ 493 resolution = Pinhole1D(self.x, 0.001*np.ones_like(self.x), 494 q_calc=self.x) 495 theory = 12.0-1000.0*resolution.q_calc 496 output = resolution.apply(theory) 497 answer = [ 10.44785079, 9.84991299, 8.98101708, 498 7.99906585, 6.99998311, 6.00001689, 499 5.00093415, 4.01898292, 3.15008701, 2.55214921] 500 np.testing.assert_allclose(output, answer, atol=1e-8) 501 502 503 class IgorComparisonTest(unittest.TestCase): 504 505 def setUp(self): 506 self.pars = TEST_PARS_PINHOLE_SPHERE 507 from sasmodels import core 508 from sasmodels.models import sphere 509 self.model = core.load_model(sphere, dtype='double') 510 511 def Iq_sphere(self, pars, resolution): 512 from sasmodels import core 513 kernel = core.make_kernel(self.model, [resolution.q_calc]) 514 theory = core.call_kernel(kernel, pars) 515 result = resolution.apply(theory) 516 kernel.release() 517 return result 518 519 def compare(self, q, output, answer, tolerance): 520 err = (output - answer)/answer 521 idx = abs(err) >= tolerance 522 problem = zip(q[idx], output[idx], answer[idx], err[idx]) 523 print "\n".join(str(v) for v in problem) 524 np.testing.assert_allclose(output, answer, rtol=tolerance) 525 526 def test_perfect(self): 527 """ 528 Compare sphere model with NIST Igor SANS, no resolution smearing. 529 """ 530 pars = TEST_PARS_SLIT_SPHERE 531 data_string = TEST_DATA_SLIT_SPHERE 532 533 data = np.loadtxt(data_string.split('\n')).T 534 q, width, answer, _ = data 535 resolution = Perfect1D(q) 536 output = self.Iq_sphere(pars, resolution) 537 self.compare(q, output, answer, 1e-6) 538 539 def test_pinhole(self): 540 """ 541 Compare pinhole resolution smearing with NIST Igor SANS 542 """ 543 pars = TEST_PARS_PINHOLE_SPHERE 544 data_string = TEST_DATA_PINHOLE_SPHERE 545 546 data = np.loadtxt(data_string.split('\n')).T 547 q, q_width, answer = data 548 resolution = Pinhole1D(q, q_width) 549 output = self.Iq_sphere(pars, resolution) 550 # TODO: relative error should be lower 551 self.compare(q, output, answer, 3e-4) 552 553 def test_pinhole_romberg(self): 554 """ 555 Compare pinhole resolution smearing with romberg integration result. 556 """ 557 pars = TEST_PARS_PINHOLE_SPHERE 558 data_string = TEST_DATA_PINHOLE_SPHERE 559 pars['radius'] *= 5 560 radius = pars['radius'] 561 562 data = np.loadtxt(data_string.split('\n')).T 563 q, q_width, answer = data 564 answer = romberg_pinhole_1d(q, q_width, self.model, pars) 565 ## Getting 0.1% requires 5 sigma and 200 points per fringe 566 #q_calc = interpolate(pinhole_extend_q(q, q_width, nsigma=5), 567 # 2*np.pi/radius/200) 568 #tol = 0.001 569 ## The default 3 sigma and no extra points gets 1% 570 q_calc, tol = None, 0.01 571 resolution = Pinhole1D(q, q_width, q_calc=q_calc) 572 output = self.Iq_sphere(pars, resolution) 573 if 0: # debug plot 574 import matplotlib.pyplot as plt 575 resolution = Perfect1D(q) 576 source = self.Iq_sphere(pars, resolution) 577 plt.loglog(q, source, '.') 578 plt.loglog(q, answer, '-', hold=True) 579 plt.loglog(q, output, '-', hold=True) 580 plt.show() 581 self.compare(q, output, answer, tol) 582 583 def test_slit(self): 584 """ 585 Compare slit resolution smearing with NIST Igor SANS 586 """ 587 pars = TEST_PARS_SLIT_SPHERE 588 data_string = TEST_DATA_SLIT_SPHERE 589 590 data = np.loadtxt(data_string.split('\n')).T 591 q, delta_qv, _, answer = data 592 resolution = Slit1D(q, width=delta_qv, height=0) 593 output = self.Iq_sphere(pars, resolution) 594 # TODO: eliminate Igor test since it is too inaccurate to be useful. 595 # This means we can eliminate the test data as well, and instead 596 # use a generated q vector. 597 self.compare(q, output, answer, 0.5) 598 599 def test_slit_romberg(self): 600 """ 601 Compare slit resolution smearing with romberg integration result. 602 """ 603 pars = TEST_PARS_SLIT_SPHERE 604 data_string = TEST_DATA_SLIT_SPHERE 605 radius = pars['radius'] 606 607 data = np.loadtxt(data_string.split('\n')).T 608 q, delta_qv, _, answer = data 609 answer = romberg_slit_1d(q, delta_qv, self.model, pars) 610 q_calc = slit_extend_q(interpolate(q, 2*np.pi/radius/20), 611 delta_qv[0], delta_qv[0]) 612 resolution = Slit1D(q, width=delta_qv, height=0, q_calc=q_calc) 613 output = self.Iq_sphere(pars, resolution) 614 # TODO: relative error should be lower 615 self.compare(q, output, answer, 0.025) 616 617 def test_ellipsoid(self): 618 """ 619 Compare romberg integration for ellipsoid model. 620 """ 621 from .core import load_model 622 pars = { 623 'scale':0.05, 624 'rpolar':500, 'requatorial':15000, 625 'sld':6, 'solvent_sld': 1, 626 } 627 form = load_model('ellipsoid', dtype='double') 628 q = np.logspace(log10(4e-5),log10(2.5e-2), 68) 629 delta_qv = [0.117] 630 resolution = Slit1D(q, width=delta_qv, height=0) 631 answer = romberg_slit_1d(q, delta_qv, form, pars) 632 output = resolution.apply(eval_form(resolution.q_calc, form, pars)) 633 # TODO: 10% is too much error; use better algorithm 634 self.compare(q, output, answer, 0.1) 635 636 #TODO: can sas q spacing be too sparse for the resolution calculation? 637 @unittest.skip("suppress sparse data test; not supported by current code") 638 def test_pinhole_sparse(self): 639 """ 640 Compare pinhole resolution smearing with NIST Igor SANS on sparse data 641 """ 642 pars = TEST_PARS_PINHOLE_SPHERE 643 data_string = TEST_DATA_PINHOLE_SPHERE 644 645 data = np.loadtxt(data_string.split('\n')).T 646 q, q_width, answer = data[:, ::20] # Take every nth point 647 resolution = Pinhole1D(q, q_width) 648 output = self.Iq_sphere(pars, resolution) 649 self.compare(q, output, answer, 1e-6) 650 651 652 # pinhole sphere parameters 653 TEST_PARS_PINHOLE_SPHERE = { 654 'scale': 1.0, 'background': 0.01, 655 'radius': 60.0, 'sld': 1, 'solvent_sld': 6.3, 656 } 657 # Q, dQ, I(Q) calculated by NIST Igor SANS package 658 TEST_DATA_PINHOLE_SPHERE = """\ 659 0.001278 0.0002847 2538.41176383 660 0.001562 0.0002905 2536.91820405 661 0.001846 0.0002956 2535.13182479 662 0.002130 0.0003017 2533.06217813 663 0.002414 0.0003087 2530.70378586 664 0.002698 0.0003165 2528.05024192 665 0.002982 0.0003249 2525.10408349 666 0.003266 0.0003340 2521.86667499 667 0.003550 0.0003437 2518.33907750 668 0.003834 0.0003539 2514.52246995 669 0.004118 0.0003646 2510.41798319 670 0.004402 0.0003757 2506.02690988 671 0.004686 0.0003872 2501.35067884 672 0.004970 0.0003990 2496.38678318 673 0.005253 0.0004112 2491.16237596 674 0.005537 0.0004237 2485.63911673 675 0.005821 0.0004365 2479.83657083 676 0.006105 0.0004495 2473.75676948 677 0.006389 0.0004628 2467.40145990 678 0.006673 0.0004762 2460.77293372 679 0.006957 0.0004899 2453.86724627 680 0.007241 0.0005037 2446.69623838 681 0.007525 0.0005177 2439.25775219 682 0.007809 0.0005318 2431.55421398 683 0.008093 0.0005461 2423.58785521 684 0.008377 0.0005605 2415.36158137 685 0.008661 0.0005750 2406.87009473 686 0.008945 0.0005896 2398.12841186 687 0.009229 0.0006044 2389.13360806 688 0.009513 0.0006192 2379.88958042 689 0.009797 0.0006341 2370.39776774 690 0.010080 0.0006491 2360.69528793 691 0.010360 0.0006641 2350.85169027 692 0.010650 0.0006793 2340.42023633 693 0.010930 0.0006945 2330.11206013 694 0.011220 0.0007097 2319.20109972 695 0.011500 0.0007251 2308.43503981 696 0.011780 0.0007404 2297.44820179 697 0.012070 0.0007558 2285.83853677 698 0.012350 0.0007713 2274.41290746 699 0.012640 0.0007868 2262.36219581 700 0.012920 0.0008024 2250.51169731 701 0.013200 0.0008180 2238.45596231 702 0.013490 0.0008336 2225.76495666 703 0.013770 0.0008493 2213.29618391 704 0.014060 0.0008650 2200.19110751 705 0.014340 0.0008807 2187.34050325 706 0.014620 0.0008965 2174.30529864 707 0.014910 0.0009123 2160.61632548 708 0.015190 0.0009281 2147.21038112 709 0.015470 0.0009440 2133.62023580 710 0.015760 0.0009598 2119.37907426 711 0.016040 0.0009757 2105.45234903 712 0.016330 0.0009916 2090.86319102 713 0.016610 0.0010080 2076.60576032 714 0.016890 0.0010240 2062.19214565 715 0.017180 0.0010390 2047.10550219 716 0.017460 0.0010550 2032.38715621 717 0.017740 0.0010710 2017.52560123 718 0.018030 0.0010880 2001.99124318 719 0.018310 0.0011040 1986.84662060 720 0.018600 0.0011200 1971.03389745 721 0.018880 0.0011360 1955.61395119 722 0.019160 0.0011520 1940.08291563 723 0.019450 0.0011680 1923.87672225 724 0.019730 0.0011840 1908.10656374 725 0.020020 0.0012000 1891.66297192 726 0.020300 0.0012160 1875.66789021 727 0.020580 0.0012320 1859.56357196 728 0.020870 0.0012490 1842.79468290 729 0.021150 0.0012650 1826.50064489 730 0.021430 0.0012810 1810.11533702 731 0.021720 0.0012970 1793.06840882 732 0.022000 0.0013130 1776.51153580 733 0.022280 0.0013290 1759.87201249 734 0.022570 0.0013460 1742.57354412 735 0.022850 0.0013620 1725.79397319 736 0.023140 0.0013780 1708.35831550 737 0.023420 0.0013940 1691.45256069 738 0.023700 0.0014110 1674.48561783 739 0.023990 0.0014270 1656.86525366 740 0.024270 0.0014430 1639.79847285 741 0.024550 0.0014590 1622.68887088 742 0.024840 0.0014760 1604.96421100 743 0.025120 0.0014920 1587.85768129 744 0.025410 0.0015080 1569.99297335 745 0.025690 0.0015240 1552.84580279 746 0.025970 0.0015410 1535.54074115 747 0.026260 0.0015570 1517.75249337 748 0.026540 0.0015730 1500.40115023 749 0.026820 0.0015900 1483.03632237 750 0.027110 0.0016060 1465.05942429 751 0.027390 0.0016220 1447.67682181 752 0.027670 0.0016390 1430.46495191 753 0.027960 0.0016550 1412.49232282 754 0.028240 0.0016710 1395.13182318 755 0.028520 0.0016880 1377.93439837 756 0.028810 0.0017040 1359.99528971 757 0.029090 0.0017200 1342.67274512 758 0.029370 0.0017370 1325.55375609 759 """ 760 761 # Slit sphere parameters 762 TEST_PARS_SLIT_SPHERE = { 763 'scale': 0.01, 'background': 0.01, 764 'radius': 60000, 'sld': 1, 'solvent_sld': 4, 765 } 766 # Q dQ I(Q) I_smeared(Q) 767 TEST_DATA_SLIT_SPHERE = """\ 768 2.26097e-05 0.117 5.5781372896e+09 1.4626077708e+06 769 2.53847e-05 0.117 5.0363141458e+09 1.3117318023e+06 770 2.81597e-05 0.117 4.4850108103e+09 1.1594863713e+06 771 3.09347e-05 0.117 3.9364658459e+09 1.0094881630e+06 772 3.37097e-05 0.117 3.4019975074e+09 8.6518941303e+05 773 3.92597e-05 0.117 2.4139519814e+09 6.0232158311e+05 774 4.48097e-05 0.117 1.5816877820e+09 3.8739994090e+05 775 5.03597e-05 0.117 9.3715407224e+08 2.2745304775e+05 776 5.59097e-05 0.117 4.8387917428e+08 1.2101295768e+05 777 6.14597e-05 0.117 2.0193586928e+08 6.0055107771e+04 778 6.70097e-05 0.117 5.5886110911e+07 3.2749521065e+04 779 7.25597e-05 0.117 3.7782348010e+06 2.6350963616e+04 780 7.81097e-05 0.117 5.3407817904e+06 2.9624963314e+04 781 8.36597e-05 0.117 2.7975485523e+07 3.4403962254e+04 782 8.92097e-05 0.117 4.9845448282e+07 3.6130017903e+04 783 9.47597e-05 0.117 6.0092588905e+07 3.3495107849e+04 784 1.00310e-04 0.117 5.6823430831e+07 2.7475726279e+04 785 1.05860e-04 0.117 4.3857024036e+07 2.0144282226e+04 786 1.11410e-04 0.117 2.7277144760e+07 1.3647403260e+04 787 1.22510e-04 0.117 3.3119334113e+06 6.6519711526e+03 788 1.33610e-04 0.117 1.4412859402e+06 6.9726212813e+03 789 1.44710e-04 0.117 8.5620162463e+06 8.1441335775e+03 790 1.55810e-04 0.117 9.6957429033e+06 6.4559996521e+03 791 1.66910e-04 0.117 4.3818341914e+06 3.6252154156e+03 792 1.78010e-04 0.117 2.7448997387e+05 2.4006505342e+03 793 1.89110e-04 0.117 8.0472009936e+05 2.8187789089e+03 794 2.00210e-04 0.117 2.8149552834e+06 3.0915662855e+03 795 2.11310e-04 0.117 2.7510907861e+06 2.3722530293e+03 796 2.22410e-04 0.117 1.0053133293e+06 1.4473468311e+03 797 2.33510e-04 0.117 5.8428305052e+03 1.2048540556e+03 798 2.44610e-04 0.117 5.1699305004e+05 1.4625670042e+03 799 2.55710e-04 0.117 1.2120227268e+06 1.5010705973e+03 800 2.66810e-04 0.117 9.7896842846e+05 1.1336343426e+03 801 2.77910e-04 0.117 2.5507264791e+05 8.1848818080e+02 802 3.05660e-04 0.117 5.2403101181e+05 7.4913374357e+02 803 3.33410e-04 0.117 5.8699343809e+04 4.4669964560e+02 804 3.61160e-04 0.117 3.0844327150e+05 4.6774007542e+02 805 3.88910e-04 0.117 8.3360142970e+03 2.7169550220e+02 806 4.16660e-04 0.117 1.8630080583e+05 3.0710983679e+02 807 4.44410e-04 0.117 3.1616804732e-01 1.7959006831e+02 808 4.72160e-04 0.117 1.1299016314e+05 2.0763952339e+02 809 4.99910e-04 0.117 2.9952522747e+03 1.2536542765e+02 810 5.27660e-04 0.117 6.7625695649e+04 1.4013969777e+02 811 5.55410e-04 0.117 7.6927460089e+03 8.2145593180e+01 812 6.10910e-04 0.117 1.1229057779e+04 8.4519745643e+01 813 6.66410e-04 0.117 1.3035567943e+04 8.1554625609e+01 814 7.21910e-04 0.117 1.3309931343e+04 7.4437319172e+01 815 7.77410e-04 0.117 1.2462626212e+04 6.4697088261e+01 816 8.32910e-04 0.117 1.0912927143e+04 5.3773301044e+01 817 8.88410e-04 0.117 9.0172597469e+03 4.2843375753e+01 818 9.43910e-04 0.117 7.0496495917e+03 3.2771032724e+01 819 9.99410e-04 0.117 5.2030483682e+03 2.4113557144e+01 820 1.05491e-03 0.117 3.5988976711e+03 1.7160773658e+01 821 1.11041e-03 0.117 2.2996060652e+03 1.2016626459e+01 822 1.22141e-03 0.117 6.4766590598e+02 6.0373017740e+00 823 1.33241e-03 0.117 4.1963483264e+01 4.5215452974e+00 824 1.44341e-03 0.117 6.3370708246e+01 5.1054681903e+00 825 1.55441e-03 0.117 3.0736750577e+02 5.9176165298e+00 826 1.66541e-03 0.117 5.0327682399e+02 5.9815000189e+00 827 1.77641e-03 0.117 5.4084331454e+02 5.1634639625e+00 828 1.88741e-03 0.117 4.3488671756e+02 3.8535158148e+00 829 1.99841e-03 0.117 2.6322287860e+02 2.5824997753e+00 830 2.10941e-03 0.117 1.0793633150e+02 1.7315517194e+00 831 2.22041e-03 0.117 1.8474448850e+01 1.4077213604e+00 832 2.33141e-03 0.117 1.5864062279e+00 1.4771560682e+00 833 2.44241e-03 0.117 3.2267213848e+01 1.6916253448e+00 834 2.55341e-03 0.117 7.4289116207e+01 1.8274751193e+00 835 2.66441e-03 0.117 9.9000521929e+01 1.7706812289e+00 836 """ 837 838 def main(): 839 """ 840 Run tests given is sys.argv. 841 842 Returns 0 if success or 1 if any tests fail. 843 """ 844 import sys 845 import xmlrunner 846 847 suite = unittest.TestSuite() 848 suite.addTest(unittest.defaultTestLoader.loadTestsFromModule(sys.modules[__name__])) 849 850 runner = xmlrunner.XMLTestRunner(output='logs') 851 result = runner.run(suite) 852 return 1 if result.failures or result.errors else 0 853 854 855 ############################################################################ 856 # usage demo 857 ############################################################################ 858 859 def _eval_demo_1d(resolution, title): 860 from sasmodels import core 861 from sasmodels.models import cylinder 862 ## or alternatively: 863 # cylinder = core.load_model_definition('cylinder') 864 model = core.load_model(cylinder) 865 866 kernel = core.make_kernel(model, [resolution.q_calc]) 867 theory = core.call_kernel(kernel, {'length':210, 'radius':500}) 868 Iq = resolution.apply(theory) 869 870 import matplotlib.pyplot as plt 871 plt.loglog(resolution.q_calc, theory, label='unsmeared') 872 plt.loglog(resolution.q, Iq, label='smeared', hold=True) 873 plt.legend() 874 plt.title(title) 875 plt.xlabel("Q (1/Ang)") 876 plt.ylabel("I(Q) (1/cm)") 877 878 def demo_pinhole_1d(): 879 q = np.logspace(-3, -1, 400) 880 q_width = 0.1*q 881 resolution = Pinhole1D(q, q_width) 882 _eval_demo_1d(resolution, title="10% dQ/Q Pinhole Resolution") 883 884 def demo_slit_1d(): 885 q = np.logspace(-3, -1, 400) 886 qx_width = 0.005 887 qy_width = 0.0 888 resolution = Slit1D(q, qx_width, qy_width) 889 _eval_demo_1d(resolution, title="0.005 Qx Slit Resolution") 890 891 def demo(): 892 import matplotlib.pyplot as plt 893 plt.subplot(121) 894 demo_pinhole_1d() 895 plt.subplot(122) 896 demo_slit_1d() 897 plt.show() 898 899 900 if __name__ == "__main__": 901 #demo() 902 main() -
src/sas/perspectives/fitting/fitting.py
rf76bf17 ra3f125f0 954 954 return True 955 955 except: 956 raise 956 957 msg = "Fitting error: %s" % str(sys.exc_value) 957 958 wx.PostEvent(self.parent, StatusEvent(status=msg, info="error", -
src/sas/perspectives/fitting/model_thread.py
r2f4b430 ra3f125f0 169 169 first_bin, last_bin = self.smearer.get_bin_range(self.qmin, 170 170 self.qmax) 171 mask = self.data.x[first_bin:last_bin ]172 output[first_bin:last_bin ] = self.model.evalDistribution(mask)171 mask = self.data.x[first_bin:last_bin+1] 172 output[first_bin:last_bin+1] = self.model.evalDistribution(mask) 173 173 output = self.smearer(output, first_bin, last_bin) 174 174 else:
Note: See TracChangeset
for help on using the changeset viewer.