Changeset 6bd3a8d1 in sasview for src/sas/calculator/resolution_calculator.py
- Timestamp:
- Mar 2, 2015 4:09:46 PM (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:
- 13e46abe
- Parents:
- c93122e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/calculator/resolution_calculator.py
r79492222 r6bd3a8d1 25 25 """ 26 26 def __init__(self): 27 27 28 28 # wavelength 29 29 self.wave = Neutron() … … 85 85 self.qxrange = [] 86 86 self.qyrange = [] 87 87 88 88 def compute_and_plot(self, qx_value, qy_value, qx_min, qx_max, 89 89 qy_min, qy_max, coord='cartesian'): … … 122 122 sigma_r, qx_min, qx_max, qy_min, qy_max, 123 123 coord, False) 124 125 # Non tof mode to be speed up126 #if num_lamda < 2:127 # return self.plot_image(image)128 129 124 if qx_min > self.qx_min: 130 125 qx_min = self.qx_min … … 135 130 if qy_max < self.qy_max: 136 131 qy_max = self.qy_max 137 132 138 133 # set max qranges 139 134 self.qxrange = [qx_min, qx_max] … … 167 162 sigma1d += sigma1d_list[ind] * sigma1d_list[ind] * self.intensity 168 163 total_intensity += self.intensity 169 164 170 165 if total_intensity != 0: 171 166 # average variance … … 195 190 else: 196 191 self.image = image_out 197 192 198 193 # plot image 199 194 return self.plot_image(self.image) 200 195 201 196 def setup_tof(self, wavelength, wavelength_spread): 202 197 """ 203 198 Setup all parameters in instrument 204 199 205 200 : param ind: index of lambda, etc 206 201 """ … … 210 205 self.set_wavelength_spread(wavelength_spread) 211 206 self.intensity = self.wave.get_intensity() 212 207 213 208 if wavelength == 0: 214 209 msg = "Can't compute the resolution: the wavelength is zero..." 215 210 raise RuntimeError, msg 216 211 return self.intensity 217 212 218 213 def compute(self, wavelength, wavelength_spread, qx_value, qy_value, 219 214 coord='cartesian', tof=False): … … 260 255 # sample to detector distance 261 256 l_two = l_sad - l_sas 262 257 263 258 # Sample offset correction for l_one and Lp on variance calculation 264 259 l1_cor = (l_ssa * l_two) / (l_sas + l_two) … … 297 292 # normalize 298 293 variance_1d_1 = knot * knot * variance_1d_1 / 12 299 294 300 295 # for 2d 301 296 #sigma_1 += sigma_wave_1 … … 328 323 # normalize 329 324 variance_1d_2 = knot * knot * variance_1d_2 / 12 330 325 331 326 # for 2d 332 327 #sigma_2 = knot*sqrt(sigma_2/12) … … 341 336 self.sigma_1d = sigma1d 342 337 return qr_value, phi, sigma_1, sigma_2, sigma_r, sigma1d 343 338 344 339 def _within_detector_range(self, qx_value, qy_value): 345 340 """ … … 364 359 return False 365 360 return True 366 361 367 362 def get_image(self, qx_value, qy_value, sigma_1, sigma_2, sigma_r, 368 363 qx_min, qx_max, qy_min, qy_max, … … 378 373 # Get qx_max and qy_max... 379 374 self._get_detector_qxqy_pixels() 380 375 381 376 qr_value, phi = self._get_polar_value(qx_value, qy_value) 382 377 … … 397 392 if not full_cal: 398 393 return None 399 394 400 395 # Make an empty graph in the detector scale 401 396 dx_size = (self.qx_max - self.qx_min) / (1000 - 1) … … 421 416 # qy_center 422 417 qc_2 = qy_value 423 418 424 419 # Calculate the 2D Gaussian distribution image 425 420 image = self._gaussian2d(q_1, q_2, qc_1, qc_2, … … 436 431 else: 437 432 self.image_lam = image * self.intensity 438 433 439 434 return self.image_lam 440 435 441 436 def plot_image(self, image): 442 437 """ 443 438 Plot image using pyplot 444 439 : image: 2d resolution image 445 440 446 441 : return plt: pylab object 447 442 """ … … 463 458 464 459 return plt 465 460 466 461 def reset_image(self): 467 462 """ … … 469 464 """ 470 465 self.image = [] 471 466 472 467 def get_variance(self, size=[], distance=0, phi=0, comp='radial'): 473 468 """ … … 476 471 : distance: [z, x] where z along the incident beam, x // qx_value 477 472 : comp: direction of the sigma; can be 'phi', 'y', 'x', and 'radial' 478 473 479 474 : return variance: sigma^2 480 475 """ 481 476 # check the length of size (list) 482 477 len_size = len(size) 483 478 484 479 # define sigma component direction 485 480 if comp == 'radial': … … 522 517 """ 523 518 Get the variance when the wavelength spread is given 524 519 525 520 : radius: the radial distance from the beam center to the pix of q 526 521 : distance: sample to detector distance 527 522 : spread: wavelength spread (ratio) 528 523 : comp: direction of the sigma; can be 'phi', 'y', 'x', and 'radial' 529 524 530 525 : return variance: sigma^2 for 2d, sigma^2 for 1d [tuple] 531 526 """ … … 560 555 else: 561 556 sigma *= 1 562 557 563 558 return sigma, sigma1d 564 559 … … 567 562 """ 568 563 Get the variance from gravity when the wavelength spread is given 569 564 570 565 : s_distance: source to sample distance 571 566 : d_distance: sample to detector distance … … 573 568 : spread: wavelength spread (ratio) 574 569 : comp: direction of the sigma; can be 'phi', 'y', 'x', and 'radial' 575 570 576 571 : return variance: sigma^2 577 572 """ … … 590 585 sigma *= math.pow(spread, 2) 591 586 sigma *= 8 592 593 # only for the polar coordinate594 #if comp == 'radial':595 # sigma *= (math.sin(phi) * math.sin(phi))596 #elif comp == 'phi':597 # sigma *= (math.cos(phi) * math.cos(phi))598 599 587 return sigma 600 588 601 589 def _cal_A_value(self, lamda, s_distance, d_distance): 602 590 """ 603 591 Calculate A value for gravity 604 592 605 593 : s_distance: source to sample distance 606 594 : d_distance: sample to detector distance … … 624 612 a_value *= (4 * lamda * lamda) 625 613 return a_value 626 614 627 615 def get_intensity(self): 628 616 """ … … 636 624 """ 637 625 return self.wave.wavelength 638 639 #TODO: why was this method duplicated? 640 #def get_spectrum(self): 641 # """ 642 # Get spectrum 643 # """ 644 # return self.wave.spectrum 645 626 646 627 def get_default_spectrum(self): 647 628 """ … … 649 630 """ 650 631 return self.wave.get_default_spectrum() 651 632 652 633 def get_spectrum(self): 653 634 """ … … 655 636 """ 656 637 return self.wave.get_spectrum() 657 638 658 639 def get_wavelength_spread(self): 659 640 """ … … 661 642 """ 662 643 return self.wave.wavelength_spread 663 644 664 645 def get_neutron_mass(self): 665 646 """ … … 667 648 """ 668 649 return self.wave.mass 669 650 670 651 def get_source_aperture_size(self): 671 652 """ … … 673 654 """ 674 655 return self.aperture.source_size 675 656 676 657 def get_sample_aperture_size(self): 677 658 """ … … 679 660 """ 680 661 return self.aperture.sample_size 681 662 682 663 def get_detector_pix_size(self): 683 664 """ … … 685 666 """ 686 667 return self.detector.pix_size 687 668 688 669 def get_detector_size(self): 689 670 """ … … 691 672 """ 692 673 return self.detector.size 693 674 694 675 def get_source2sample_distance(self): 695 676 """ … … 697 678 """ 698 679 return self.aperture.sample_distance 699 680 700 681 def get_sample2sample_distance(self): 701 682 """ … … 703 684 """ 704 685 return self.sample.distance 705 686 706 687 def get_sample2detector_distance(self): 707 688 """ … … 709 690 """ 710 691 return self.detector.distance 711 692 712 693 def set_intensity(self, intensity): 713 694 """ … … 715 696 """ 716 697 self.wave.set_intensity(intensity) 717 698 718 699 def set_wave(self, wavelength): 719 700 """ … … 727 708 else: 728 709 raise 729 710 730 711 def set_wave_spread(self, wavelength_spread): 731 712 """ … … 736 717 elif wavelength_spread.__class__.__name__ == 'float': 737 718 self.wave.set_wave_spread_list([wavelength_spread]) 738 #self.set_wavelength_spread(wavelength_spread)739 719 else: 740 720 raise 741 721 742 722 def set_wavelength(self, wavelength): 743 723 """ … … 746 726 self.wavelength = wavelength 747 727 self.wave.set_wavelength(wavelength) 748 728 749 729 def set_spectrum(self, spectrum): 750 730 """ … … 753 733 self.spectrum = spectrum 754 734 self.wave.set_spectrum(spectrum) 755 735 756 736 def set_wavelength_spread(self, wavelength_spread): 757 737 """ … … 760 740 self.wavelength_spread = wavelength_spread 761 741 self.wave.set_wavelength_spread(wavelength_spread) 762 742 763 743 def set_wave_list(self, wavelength_list, wavelengthspread_list): 764 744 """ … … 767 747 self.wave.set_wave_list(wavelength_list) 768 748 self.wave.set_wave_spread_list(wavelengthspread_list) 769 749 770 750 def get_wave_list(self): 771 751 """ … … 773 753 """ 774 754 return self.wave.get_wave_list() 775 755 776 756 def get_intensity_list(self): 777 757 """ … … 779 759 """ 780 760 return self.wave.get_intensity_list() 781 761 782 762 def set_source_aperture_size(self, size): 783 763 """ 784 764 Set source aperture size 785 765 786 766 : param size: [dia_value] or [x_value, y_value] 787 767 """ … … 789 769 raise RuntimeError, "The length of the size must be one or two." 790 770 self.aperture.set_source_size(size) 791 771 792 772 def set_neutron_mass(self, mass): 793 773 """ … … 796 776 self.wave.set_mass(mass) 797 777 self.mass = mass 798 778 799 779 def set_sample_aperture_size(self, size): 800 780 """ 801 781 Set sample aperture size 802 782 803 783 : param size: [dia_value] or [xheight_value, yheight_value] 804 784 """ … … 806 786 raise RuntimeError, "The length of the size must be one or two." 807 787 self.aperture.set_sample_size(size) 808 788 809 789 def set_detector_pix_size(self, size): 810 790 """ … … 812 792 """ 813 793 self.detector.set_pix_size(size) 814 794 815 795 def set_detector_size(self, size): 816 796 """ … … 819 799 """ 820 800 self.detector.set_size(size) 821 801 822 802 def set_source2sample_distance(self, distance): 823 803 """ 824 804 Set detector source2sample_distance 825 805 826 806 : param distance: [distance, x_offset] 827 807 """ … … 833 813 """ 834 814 Set detector sample_slit2sample_distance 835 815 836 816 : param distance: [distance, x_offset] 837 817 """ … … 839 819 raise RuntimeError, "The length of the size must be one or two." 840 820 self.sample.set_distance(distance) 841 821 842 822 def set_sample2detector_distance(self, distance): 843 823 """ 844 824 Set detector sample2detector_distance 845 825 846 826 : param distance: [distance, x_offset] 847 827 """ … … 849 829 raise RuntimeError, "The length of the size must be one or two." 850 830 self.detector.set_distance(distance) 851 831 852 832 def get_all_instrument_params(self): 853 833 """ 854 834 Get all instrumental parameters 855 835 """ 856 #self.intensity = self.get_intensity()857 #self.wavelength = self.get_wavelength()858 #self.wavelength_spread = self.get_wavelength_spread()859 836 self.mass = self.get_neutron_mass() 860 837 self.spectrum = self.get_spectrum() … … 866 843 self.sample2sample_distance = self.get_sample2sample_distance() 867 844 self.sample2detector_distance = self.get_sample2detector_distance() 868 845 869 846 def get_detector_qrange(self): 870 847 """ 871 848 get max detector q ranges 872 849 873 850 : return: qx_min, qx_max, qy_min, qy_max tuple 874 851 """ … … 879 856 qy_min = self.qyrange[0] 880 857 qy_max = self.qyrange[1] 881 858 882 859 return qx_min, qx_max, qy_min, qy_max 883 860 884 861 def _rotate_z(self, x_value, y_value, theta=0.0): 885 862 """ … … 888 865 : y_value: numpy array of y values 889 866 : theta: angle to rotate by in rad 890 867 891 868 :return: x_prime, y-prime 892 """ 869 """ 893 870 # rotate by theta 894 871 x_prime = x_value * math.cos(theta) + y_value * math.sin(theta) 895 872 y_prime = -x_value * math.sin(theta) + y_value * math.cos(theta) 896 873 897 874 return x_prime, y_prime 898 875 899 876 def _gaussian2d(self, x_val, y_val, x0_val, y0_val, 900 877 sigma_x, sigma_y, sigma_r): … … 907 884 : sigma_x: variance in x-direction 908 885 : sigma_y: variance in y-direction 909 886 910 887 : return: gaussian (value) 911 888 """ … … 914 891 y_value = y_val - y0_val 915 892 phi_i = numpy.arctan2(y_val, x_val) 916 893 917 894 # phi correction due to the gravity shift (in phi) 918 895 phi_0 = math.atan2(y0_val, x0_val) … … 921 898 sin_phi = numpy.sin(self.gravity_phi) 922 899 cos_phi = numpy.cos(self.gravity_phi) 923 900 924 901 x_p = x_value * cos_phi + y_value * sin_phi 925 902 y_p = -x_value * sin_phi + y_value * cos_phi 926 903 927 904 new_sig_x = sqrt(sigma_r * sigma_r / (sigma_x * sigma_x) + 1) 928 905 new_sig_y = sqrt(sigma_r * sigma_r / (sigma_y * sigma_y) + 1) … … 951 928 : sigma_y: variance in phi-direction 952 929 : sigma_r: wavelength variance in r-direction 953 930 954 931 : return: gaussian (value) 955 932 """ … … 958 935 gaussian = self._gaussian1d(x_val, x0_val, sigma_x) 959 936 gaussian *= self._gaussian1d(y_val, y0_val, sigma_y) 960 937 961 938 # normalizing factor correction 962 939 if sigma_x != 0 and sigma_y != 0: 963 940 gaussian *= sqrt(2 * pi) 964 941 return gaussian 965 942 966 943 def _gaussian1d(self, value, mean, sigma): 967 944 """ … … 970 947 : mean: mean value 971 948 : sigma: variance 972 949 973 950 : return: gaussian (value) 974 951 """ … … 984 961 # normalize 985 962 gaussian /= sqrt(2 * pi) 986 963 987 964 return gaussian 988 965 989 966 def _atan_phi(self, qy_value, qx_value): 990 967 """ … … 992 969 : qx_value: x component of q 993 970 : qy_value: y component of q 994 971 995 972 : return phi: the azimuthal angle of q on x-y plane 996 973 """ … … 1019 996 Get the pixel positions of the detector in the qx_value-qy_value space 1020 997 """ 1021 998 1022 999 # update all param values 1023 1000 self.get_all_instrument_params() 1024 1001 1025 1002 # wavelength 1026 1003 wavelength = self.wave.wavelength 1027 1004 # Gavity correction 1028 1005 delta_y = self._get_beamcenter_drop() # in cm 1029 1006 1030 1007 # detector_pix size 1031 1008 detector_pix_size = self.detector_pix_size … … 1050 1027 except: 1051 1028 pass 1052 1029 1053 1030 # detector size in [no of pix_x,no of pix_y] 1054 1031 detector_pix_nums_x = self.detector_size[0] 1055 1032 1056 1033 # get pix_y if it exists, otherwse take it from [0] 1057 1034 try: … … 1059 1036 except: 1060 1037 detector_pix_nums_y = self.detector_size[0] 1061 1038 1062 1039 # detector offset in pix number 1063 1040 offset_x = detector_offset / pix_x_size 1064 1041 offset_y = delta_y / pix_y_size 1065 1042 1066 1043 # beam center position in pix number (start from 0) 1067 1044 center_x, center_y = self._get_beamcenter_position(detector_pix_nums_x, … … 1078 1055 detector_ind_x = detector_ind_x - center_x 1079 1056 detector_ind_y = detector_ind_y - center_y 1080 1057 1081 1058 # unit correction in cm 1082 1059 detector_ind_x = detector_ind_x * pix_x_size 1083 1060 detector_ind_y = detector_ind_y * pix_y_size 1084 1061 1085 1062 qx_value = numpy.zeros(len(detector_ind_x)) 1086 1063 qy_value = numpy.zeros(len(detector_ind_y)) … … 1094 1071 qy_value[i] = self._get_qx(indy, sample2detector_distance, wavelength) 1095 1072 i += 1 1096 1073 1097 1074 # qx_value and qy_value values in array 1098 1075 qx_value = qx_value.repeat(detector_pix_nums_y) … … 1107 1084 self.qy_min = numpy.min(qy_value) 1108 1085 self.qy_max = numpy.max(qy_value) 1109 1086 1110 1087 # Appr. min and max values of the detector display limits 1111 1088 # i.e., edges of the last pixels. … … 1119 1096 self.qx_max += self._get_qx(0.5 * pix_x_size, 1120 1097 sample2detector_distance, wavelength) 1121 1098 1122 1099 # min and max values of detecter 1123 1100 self.detector_qx_min = self.qx_min … … 1125 1102 self.detector_qy_min = self.qy_min 1126 1103 self.detector_qy_max = self.qy_max 1127 1104 1128 1105 # try to set it as a Data2D otherwise pass (not required for now) 1129 1106 try: … … 1136 1113 except: 1137 1114 pass 1138 1115 1139 1116 return output 1140 1117 1141 1118 def _get_qx(self, dx_size, det_dist, wavelength): 1142 1119 """ 1143 1120 :param dx_size: x-distance from beam center [cm] 1144 1121 :param det_dist: sample to detector distance [cm] 1145 1122 1146 1123 :return: q-value at the given position 1147 1124 """ … … 1152 1129 qx_value = (2.0 * pi / wavelength) * numpy.sin(theta) 1153 1130 return qx_value 1154 1131 1155 1132 def _get_polar_value(self, qx_value, qy_value): 1156 1133 """ 1157 1134 Find qr_value and phi from qx_value and qy_value values 1158 1135 1159 1136 : return qr_value, phi 1160 1137 """ … … 1163 1140 # find angle phi 1164 1141 phi = self._atan_phi(qy_value, qx_value) 1165 1142 1166 1143 return qr_value, phi 1167 1144 1168 1145 def _get_beamcenter_position(self, num_x, num_y, offset_x, offset_y): 1169 1146 """ … … 1171 1148 :param num_y: number of pixel in y-direction 1172 1149 :param offset: detector offset in x-direction in pix number 1173 1150 1174 1151 :return: pix number; pos_x, pos_y in pix index 1175 1152 """ … … 1188 1165 """ 1189 1166 Get the beam center drop (delta y) in y diection due to gravity 1190 1167 1191 1168 :return delta y: the beam center drop in cm 1192 1169 """
Note: See TracChangeset
for help on using the changeset viewer.