Changeset 39a06c9 in sasmodels
- Timestamp:
- Oct 25, 2018 5:58:26 PM (6 years ago)
- Branches:
- master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
- Children:
- 81751c2
- Parents:
- 304c775
- Location:
- sasmodels
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/generate.py
re44432d r39a06c9 24 24 dimension, or 1.0 if no volume normalization is required. 25 25 26 *ER(p1, p2, ...)* returns the effective radius of the form with 27 particular dimensions. 28 29 *VR(p1, p2, ...)* returns the volume ratio for core-shell style forms. 26 *shell_volume(p1, p2, ...)* returns the volume of the shell for forms 27 which are hollow. 28 29 *effective_radius(mode, p1, p2, ...)* returns the effective radius of 30 the form with particular dimensions. Mode determines the type of 31 effective radius returned, with mode=1 for equivalent volume. 30 32 31 33 #define INVALID(v) (expr) returns False if v.parameter is invalid … … 72 74 background. This will work correctly even when polydispersity is off. 73 75 74 *ER* and *VR* are python functions which operate on parameter vectors.75 The constructor code will generate the necessary vectors for computing76 them with the desired polydispersity.77 76 The kernel module must set variables defining the kernel meta data: 78 77 … … 106 105 create the OpenCL kernel functions. The files defining the functions 107 106 need to be listed before the files which use the functions. 108 109 *ER* is a python function defining the effective radius. If it is110 not present, the effective radius is 0.111 112 *VR* is a python function defining the volume ratio. If it is not113 present, the volume ratio is 1.114 107 115 108 *form_volume*, *Iq*, *Iqac*, *Iqabc* are strings containing -
sasmodels/mixture.py
recf895e r39a06c9 143 143 #model_info.tests = [] 144 144 #model_info.source = [] 145 # Iq, Iqxy, form_volume, ER, VR and sesans146 145 # Remember the component info blocks so we can build the model 147 146 model_info.composition = ('mixture', parts) -
sasmodels/model_test.py
r304c775 r39a06c9 10 10 11 11 Each model is tested using the default parameters at q=0.1, (qx, qy)=(0.1, 0.1), 12 and the ER and VR are computed. The return values at these points are not13 considered. The test is only to verify that the models run to completion, 14 and do not produce inf or NaN.12 and Fq is called to make sure R_eff, volume and volume ratio are computed. 13 The return values at these points are not considered. The test is only to 14 verify that the models run to completion, and do not produce inf or NaN. 15 15 16 16 Tests are defined with the *tests* attribute in the model.py file. *tests* 17 17 is a list of individual tests to run, where each test consists of the 18 18 parameter values for the test, the q-values and the expected results. For 19 the effective radius test, the q-value should be 'ER'. For the VR test, 20 the q-value should be 'VR'. For 1-D tests, either specify the q value or 21 a list of q-values, and the corresponding I(q) value, or list of I(q) values. 19 the effective radius test and volume ratio tests, use the extended output 20 form, which checks each output of kernel.Fq. For 1-D tests, either specify 21 the q value or a list of q-values, and the corresponding I(q) value, or 22 list of I(q) values. 22 23 23 24 That is:: … … 32 33 [I(qx1, qy1), I(qx2, qy2), ...]], 33 34 34 [ {parameters}, 'ER', ER(pars) ], 35 [ {parameters}, 'VR', VR(pars) ], 35 [ {parameters}, q, F(q), F^2(q), R_eff, V, V_r ], 36 36 ... 37 37 ] … … 214 214 ({}, [0.001, 0.01, 0.1], [None]*3), 215 215 ({}, [(0.1, 0.1)]*2, [None]*2), 216 # test that ER/VR will run if they exist216 # test that Fq will run 217 217 ({}, 0.1, None, None, None, None, None), 218 218 ] … … 249 249 def _find_missing_tests(self): 250 250 # type: () -> None 251 """make sure there are 1D, 2D, ER and VR tests as appropriate""" 252 model_has_VR = callable(self.info.VR) 253 model_has_ER = callable(self.info.ER) 251 """make sure there are 1D and 2D tests as appropriate""" 254 252 model_has_1D = True 255 253 model_has_2D = any(p.type == 'orientation' … … 259 257 single = [test for test in self.info.tests 260 258 if not isinstance(test[2], list) and test[2] is not None] 261 tests_has_VR = any(test[1] == 'VR' for test in single)262 tests_has_ER = any(test[1] == 'ER' for test in single)263 259 tests_has_1D_single = any(isinstance(test[1], float) for test in single) 264 260 tests_has_2D_single = any(isinstance(test[1], tuple) for test in single) … … 273 269 274 270 missing = [] 275 if model_has_VR and not tests_has_VR:276 missing.append("VR")277 if model_has_ER and not tests_has_ER:278 missing.append("ER")279 271 if model_has_1D and not (tests_has_1D_single or tests_has_1D_multiple): 280 272 missing.append("1D") -
sasmodels/modelinfo.py
rbe43e39 r39a06c9 264 264 will have a magnitude and a direction, which may be different from 265 265 other sld parameters. The volume parameters are used for calls 266 to form_volume within the kernel (required for volume normalization) 267 and for calls to ER and VR for effective radius and volume ratio268 respectively.266 to form_volume within the kernel (required for volume normalization), 267 to shell_volume (for hollow shapes), and to effective_radius (for 268 structure factor interactions) respectively. 269 269 270 270 *description* is a short description of the parameter. This will … … 799 799 info.c_code = getattr(kernel_module, 'c_code', None) 800 800 info.effective_radius = getattr(kernel_module, 'effective_radius', None) 801 info.ER = None # CRUFT802 info.VR = None # CRUFT803 801 # TODO: check the structure of the tests 804 802 info.tests = getattr(kernel_module, 'tests', []) … … 932 930 #: use those functions. 933 931 source = None # type: List[str] 934 #: The set of tests that must pass. The format of the tests is described 935 #: in :mod:`model_test`. 936 tests = None # type: List[TestCondition] 937 #: Returns the effective radius of the model given its volume parameters. 938 #: The presence of *ER* indicates that the model is a form factor model 939 #: that may be used together with a structure factor to form an implicit 940 #: multiplication model. 941 #: 942 #: The parameters to the *ER* function must be marked with type *volume*. 943 #: in the parameter table. They will appear in the same order as they 944 #: do in the table. The values passed to *ER* will be vectors, with one 945 #: value for each polydispersity condition. For example, if the model 946 #: is polydisperse over both length and radius, then both length and 947 #: radius will have the same number of values in the vector, with one 948 #: value for each *length X radius*. If only *radius* is polydisperse, 949 #: then the value for *length* will be repeated once for each value of 950 #: *radius*. The *ER* function should return one effective radius for 951 #: each parameter set. Multiplicity parameters will be received as 952 #: arrays, with one row per polydispersity condition. 953 c_code = None 932 #: inline source code, added after all elements of source 933 c_code = None # type: Optional[str] 954 934 #: Returns the form volume for python-based models. Form volume is needed 955 935 #: for volume normalization in the polydispersity integral. If no … … 1001 981 #: Line numbers for symbols defining C code 1002 982 lineno = None # type: Dict[str, int] 983 #: The set of tests that must pass. The format of the tests is described 984 #: in :mod:`model_test`. 985 tests = None # type: List[TestCondition] 1003 986 1004 987 def __init__(self): -
sasmodels/product.py
re44432d r39a06c9 61 61 return pars 62 62 63 # TODO: core_shell_sphere model has suppressed the volume ratio calculation64 # revert it after making VR and ER available at run time as constraints.65 63 def make_product_info(p_info, s_info): 66 64 # type: (ModelInfo, ModelInfo) -> ModelInfo … … 126 124 #model_info.tests = [] 127 125 #model_info.source = [] 128 # Iq, Iqxy, form_volume, ER, VR and sesans129 126 # Remember the component info blocks so we can build the model 130 127 model_info.composition = ('product', [p_info, s_info]) … … 331 328 #print("R_eff=%d:%g, volfrac=%g, volume ratio=%g"%(radius_type, effective_radius, volfrac, volume_ratio)) 332 329 if radius_type > 0: 333 # set the value to the model ERand set the weight to 1330 # set the value to the model R_eff and set the weight to 1 334 331 s_values[2] = s_values[2+s_npars+s_offset[0]] = effective_radius 335 332 s_values[2+s_npars+s_offset[0]+nweights] = 1.0 … … 366 363 self.p_kernel.release() 367 364 self.s_kernel.release() 368 369 370 def calc_er_vr(model_info, call_details, values):371 # type: (ModelInfo, ParameterSet) -> Tuple[float, float]372 373 if model_info.ER is None and model_info.VR is None:374 return 1.0, 1.0375 376 nvalues = model_info.parameters.nvalues377 value = values[nvalues:nvalues + call_details.num_weights]378 weight = values[nvalues + call_details.num_weights: nvalues + 2*call_details.num_weights]379 npars = model_info.parameters.npars380 # Note: changed from pairs ([v], [w]) to triples (p, [v], [w]), but the381 # dispersion mesh code doesn't actually care about the nominal parameter382 # value, p, so set it to None.383 pairs = [(None, value[offset:offset+length], weight[offset:offset+length])384 for p, offset, length385 in zip(model_info.parameters.call_parameters[2:2+npars],386 call_details.offset,387 call_details.length)388 if p.type == 'volume']389 value, weight = dispersion_mesh(model_info, pairs)390 391 if model_info.ER is not None:392 individual_radii = model_info.ER(*value)393 radius_effective = np.sum(weight*individual_radii) / np.sum(weight)394 else:395 radius_effective = 1.0396 397 if model_info.VR is not None:398 whole, part = model_info.VR(*value)399 volume_ratio = np.sum(weight*part)/np.sum(weight*whole)400 else:401 volume_ratio = 1.0402 403 return radius_effective, volume_ratio -
sasmodels/sasview_model.py
rbe43e39 r39a06c9 695 695 return self._calculate_Iq(qx, qy) 696 696 697 def _calculate_Iq(self, qx, qy=None ):697 def _calculate_Iq(self, qx, qy=None, Fq=False, effective_radius_type=1): 698 698 if self._model is None: 699 699 self._model = core.build_model(self._model_info) … … 715 715 #print("values", values) 716 716 #print("is_mag", is_magnetic) 717 if Fq: 718 result = calculator.Fq(call_details, values, cutoff=self.cutoff, 719 magnetic=is_magnetic, 720 effective_radius_type=effective_radius_type) 717 721 result = calculator(call_details, values, cutoff=self.cutoff, 718 722 magnetic=is_magnetic) … … 726 730 return result, lazy_results 727 731 728 def calculate_ER(self): 732 733 def calculate_ER(self, mode=1): 729 734 # type: () -> float 730 735 """ … … 733 738 :return: the value of the effective radius 734 739 """ 735 if self._model_info.ER is None: 736 return 1.0 737 else: 738 value, weight = self._dispersion_mesh() 739 fv = self._model_info.ER(*value) 740 #print(values[0].shape, weights.shape, fv.shape) 741 return np.sum(weight * fv) / np.sum(weight) 740 Fq = self._calculate_Iq([0.1], True, mode) 741 return Fq[2] 742 742 743 743 def calculate_VR(self): … … 746 746 Calculate the volf ratio for P(q)*S(q) 747 747 748 :return: the value of the volf ratio 749 """ 750 if self._model_info.VR is None: 751 return 1.0 752 else: 753 value, weight = self._dispersion_mesh() 754 whole, part = self._model_info.VR(*value) 755 return np.sum(weight * part) / np.sum(weight * whole) 748 :return: the value of the form:shell volume ratio 749 """ 750 Fq = self._calculate_Iq([0.1], True, mode) 751 return Fq[4] 756 752 757 753 def set_dispersion(self, parameter, dispersion):
Note: See TracChangeset
for help on using the changeset viewer.