Changeset fd7291e in sasmodels for sasmodels/sasview_model.py
- Timestamp:
- Mar 6, 2019 4:05:52 PM (5 years ago)
- Branches:
- master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
- Children:
- c11d09f
- Parents:
- 21c93c3 (diff), 9150036 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/sasview_model.py
r21c93c3 rfd7291e 300 300 attrs['category'] = model_info.category 301 301 attrs['is_structure_factor'] = model_info.structure_factor 302 attrs['is_form_factor'] = model_info. ERis not None302 attrs['is_form_factor'] = model_info.effective_radius_type is not None 303 303 attrs['is_multiplicity_model'] = variants[0] > 1 304 304 attrs['multiplicity_info'] = variants … … 399 399 hidden.add('scale') 400 400 hidden.add('background') 401 self._model_info.parameters.defaults['background'] = 0.402 401 403 402 # Update the parameter lists to exclude any hidden parameters … … 574 573 # pylint: disable=unpacking-non-sequence 575 574 q, phi = x 576 return self.calculate_Iq([q*math.cos(phi)], [q*math.sin(phi)])[0] 575 result, _ = self.calculate_Iq([q*math.cos(phi)], [q*math.sin(phi)]) 576 return result[0] 577 577 else: 578 return self.calculate_Iq([x])[0] 578 result, _ = self.calculate_Iq([x]) 579 return result[0] 579 580 580 581 … … 591 592 """ 592 593 if isinstance(x, (list, tuple)): 593 return self.calculate_Iq([x[0]], [x[1]])[0] 594 result, _ = self.calculate_Iq([x[0]], [x[1]]) 595 return result[0] 594 596 else: 595 return self.calculate_Iq([x])[0] 597 result, _ = self.calculate_Iq([x]) 598 return result[0] 596 599 597 600 def evalDistribution(self, qdist): … … 627 630 # Check whether we have a list of ndarrays [qx,qy] 628 631 qx, qy = qdist 629 return self.calculate_Iq(qx, qy) 632 result, _ = self.calculate_Iq(qx, qy) 633 return result 630 634 631 635 elif isinstance(qdist, np.ndarray): 632 636 # We have a simple 1D distribution of q-values 633 return self.calculate_Iq(qdist) 637 result, _ = self.calculate_Iq(qdist) 638 return result 634 639 635 640 else: … … 650 655 # so that it returns a results object containing all the bits: 651 656 # the A, B, C, ... of the composition model (and any subcomponents?) 652 # the P and S of the product model ,657 # the P and S of the product model 653 658 # the combined model before resolution smearing, 654 659 # the sasmodel before sesans conversion, … … 671 676 if composition and composition[0] == 'product': # only P*S for now 672 677 with calculation_lock: 673 self._calculate_Iq(qx) 674 return self._intermediate_results 678 _, lazy_results = self._calculate_Iq(qx) 679 # for compatibility with sasview 4.x 680 results = lazy_results() 681 pq_data = results.get("P(Q)") 682 sq_data = results.get("S(Q)") 683 return pq_data, sq_data 675 684 else: 676 685 return None 677 686 678 def calculate_Iq(self, qx, qy=None): 679 # type: (Sequence[float], Optional[Sequence[float]]) -> np.ndarray 687 def calculate_Iq(self, 688 qx, # type: Sequence[float] 689 qy=None # type: Optional[Sequence[float]] 690 ): 691 # type: (...) -> Tuple[np.ndarray, Callable[[], collections.OrderedDict[str, np.ndarray]]] 680 692 """ 681 693 Calculate Iq for one set of q with the current parameters. … … 685 697 This should NOT be used for fitting since it copies the *q* vectors 686 698 to the card for each evaluation. 699 700 The returned tuple contains the scattering intensity followed by a 701 callable which returns a dictionary of intermediate data from 702 ProductKernel. 687 703 """ 688 704 ## uncomment the following when trying to debug the uncoordinated calls … … 721 737 result = calculator(call_details, values, cutoff=self.cutoff, 722 738 magnetic=is_magnetic) 739 lazy_results = getattr(calculator, 'results', 740 lambda: collections.OrderedDict()) 723 741 #print("result", result) 724 self._intermediate_results = getattr(calculator, 'results', None) 742 725 743 calculator.release() 726 744 #self._model.release() 727 return result 728 729 def calculate_ER(self): 745 746 return result, lazy_results 747 748 749 def calculate_ER(self, mode=1): 730 750 # type: () -> float 731 751 """ 732 752 Calculate the effective radius for P(q)*S(q) 733 753 754 *mode* is the R_eff type, which defaults to 1 to match the ER 755 calculation for sasview models from version 3.x. 756 734 757 :return: the value of the effective radius 735 758 """ 736 if self._model_info.ER is None: 737 return 1.0 738 else: 739 value, weight = self._dispersion_mesh() 740 fv = self._model_info.ER(*value) 741 #print(values[0].shape, weights.shape, fv.shape) 742 return np.sum(weight * fv) / np.sum(weight) 759 # ER and VR are only needed for old multiplication models, based on 760 # sas.sascalc.fit.MultiplicationModel. Fail for now. If we want to 761 # continue supporting them then add some test cases so that the code 762 # is exercised. We can access ER/VR using the kernel Fq function by 763 # extending _calculate_Iq so that it calls: 764 # if er_mode > 0: 765 # res = calculator.Fq(call_details, values, cutoff=self.cutoff, 766 # magnetic=False, effective_radius_type=mode) 767 # R_eff, form_shell_ratio = res[2], res[4] 768 # return R_eff, form_shell_ratio 769 # Then use the following in calculate_ER: 770 # ER, VR = self._calculate_Iq(q=[0.1], er_mode=mode) 771 # return ER 772 # Similarly, for calculate_VR: 773 # ER, VR = self._calculate_Iq(q=[0.1], er_mode=1) 774 # return VR 775 # Obviously a combined calculate_ER_VR method would be better, but 776 # we only need them to support very old models, so ignore the 2x 777 # performance hit. 778 raise NotImplementedError("ER function is no longer available.") 743 779 744 780 def calculate_VR(self): … … 747 783 Calculate the volf ratio for P(q)*S(q) 748 784 749 :return: the value of the volf ratio 750 """ 751 if self._model_info.VR is None: 752 return 1.0 753 else: 754 value, weight = self._dispersion_mesh() 755 whole, part = self._model_info.VR(*value) 756 return np.sum(weight * part) / np.sum(weight * whole) 785 :return: the value of the form:shell volume ratio 786 """ 787 # See comments in calculate_ER. 788 raise NotImplementedError("VR function is no longer available.") 757 789 758 790 def set_dispersion(self, parameter, dispersion): … … 864 896 P = _make_standard_model('cylinder')() 865 897 model = MultiplicationModel(P, S) 898 model.setParam(product.RADIUS_MODE_ID, 1.0) 866 899 value = model.evalDistribution([0.1, 0.1]) 867 900 if np.isnan(value): … … 918 951 CylinderModel().evalDistribution([0.1, 0.1]) 919 952 953 def test_structure_factor_background(): 954 # type: () -> None 955 """ 956 Check that sasview model and direct model match, with background=0. 957 """ 958 from .data import empty_data1D 959 from .core import load_model_info, build_model 960 from .direct_model import DirectModel 961 962 model_name = "hardsphere" 963 q = [0.0] 964 965 sasview_model = _make_standard_model(model_name)() 966 sasview_value = sasview_model.evalDistribution(np.array(q))[0] 967 968 data = empty_data1D(q) 969 model_info = load_model_info(model_name) 970 model = build_model(model_info) 971 direct_model = DirectModel(data, model) 972 direct_value_zero_background = direct_model(background=0.0) 973 974 assert sasview_value == direct_value_zero_background 975 976 # Additionally check that direct value background defaults to zero 977 direct_value_default = direct_model() 978 assert sasview_value == direct_value_default 979 980 920 981 def magnetic_demo(): 921 982 Model = _make_standard_model('sphere') … … 924 985 q = np.linspace(-0.35, 0.35, 500) 925 986 qx, qy = np.meshgrid(q, q) 926 result = model.calculate_Iq(qx.flatten(), qy.flatten())987 result, _ = model.calculate_Iq(qx.flatten(), qy.flatten()) 927 988 result = result.reshape(qx.shape) 928 989 … … 938 999 #print("rpa:", test_rpa()) 939 1000 #test_empty_distribution() 1001 #test_structure_factor_background()
Note: See TracChangeset
for help on using the changeset viewer.