Changeset 304c775 in sasmodels
- Timestamp:
- Oct 25, 2018 3:35:06 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:
- 39a06c9
- Parents:
- 6d5601c
- Files:
-
- 22 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/guide/plugin.rst
r31fc4ad r304c775 1033 1033 "radius": 120., "radius_pd": 0.2, "radius_pd_n":45}, 1034 1034 0.2, 0.228843], 1035 [{"radius": 120., "radius_pd": 0.2, "radius_pd_n":45}, "ER", 120.],1036 [{"radius": 120., "radius_pd": 0.2, "radius_pd_n":45}, "VR", 1.],1035 [{"radius": 120., "radius_pd": 0.2, "radius_pd_n":45}, 1036 0.1, None, None, 120., None, 1.], # q, F, F^2, R_eff, V, form:shell 1037 1037 ] 1038 1038 1039 1039 1040 **tests=[[{parameters}, q, result], ...]** is a list of lists.1040 **tests=[[{parameters}, q, Iq], ...]** is a list of lists. 1041 1041 Each list is one test and contains, in order: 1042 1042 … … 1050 1050 - input and output values can themselves be lists if you have several 1051 1051 $q$ values to test for the same model parameters. 1052 - for testing *ER* and *VR*, give the inputs as "ER" and "VR" respectively; 1053 the output for *VR* should be the sphere/shell ratio, not the individual 1054 sphere and shell values. 1052 - for testing effective radius, volume and form:shell volume ratio, use the 1053 extended form of the tests results, with *None, None, R_eff, V, V_r* 1054 instead of *Iq*. This calls the kernel *Fq* function instead of *Iq*. 1055 - for testing F and F^2 (used for beta approximation) do the same as the 1056 effective radius test, but include values for the first two elements, 1057 $<F(q)>$ and $<F^2(q)>$. 1055 1058 1056 1059 .. _Test_Your_New_Model: -
sasmodels/direct_model.py
r7b9e4dd r304c775 64 64 return calculator(call_details, values, cutoff, is_magnetic) 65 65 66 def call_ER(model_info, pars): 67 # type: (ModelInfo, ParameterSet) -> float 68 """ 69 Call the model ER function using *values*. 70 71 *model_info* is either *model.info* if you have a loaded model, 72 or *kernel.info* if you have a model kernel prepared for evaluation. 73 """ 74 if model_info.ER is None: 75 return 1.0 76 elif not model_info.parameters.form_volume_parameters: 77 # handle the case where ER is provided but model is not polydisperse 78 return model_info.ER() 79 else: 80 value, weight = _vol_pars(model_info, pars) 81 individual_radii = model_info.ER(*value) 82 return np.sum(weight*individual_radii) / np.sum(weight) 83 84 85 def call_VR(model_info, pars): 86 # type: (ModelInfo, ParameterSet) -> float 87 """ 88 Call the model VR function using *pars*. 89 90 *model_info* is either *model.info* if you have a loaded model, 91 or *kernel.info* if you have a model kernel prepared for evaluation. 92 """ 93 if model_info.VR is None: 94 return 1.0 95 elif not model_info.parameters.form_volume_parameters: 96 # handle the case where ER is provided but model is not polydisperse 97 return model_info.VR() 98 else: 99 value, weight = _vol_pars(model_info, pars) 100 whole, part = model_info.VR(*value) 101 return np.sum(weight*part)/np.sum(weight*whole) 102 66 def call_Fq(calculator, pars, cutoff=0., mono=False): 67 # type: (Kernel, ParameterSet, float, bool) -> np.ndarray 68 """ 69 Like :func:`call_kernel`, but returning F, F^2, R_eff, V, V_form/V_shell. 70 """ 71 R_eff_type = int(pars.pop('radius_effective_type', 1.0)) 72 mesh = get_mesh(calculator.info, pars, dim=calculator.dim, mono=mono) 73 #print("pars", list(zip(*mesh))[0]) 74 call_details, values, is_magnetic = make_kernel_args(calculator, mesh) 75 #print("values:", values) 76 return calculator.Fq(call_details, values, cutoff, is_magnetic, R_eff_type) 103 77 104 78 def call_profile(model_info, **pars): … … 419 393 model_name = sys.argv[1] 420 394 call = sys.argv[2].upper() 421 if call != "ER_VR": 422 try: 423 values = [float(v) for v in call.split(',')] 424 except ValueError: 425 values = [] 426 if len(values) == 1: 427 q, = values 428 data = empty_data1D([q]) 429 elif len(values) == 2: 430 qx, qy = values 431 data = empty_data2D([qx], [qy]) 432 else: 433 print("use q or qx,qy or ER or VR") 434 sys.exit(1) 395 try: 396 values = [float(v) for v in call.split(',')] 397 except ValueError: 398 values = [] 399 if len(values) == 1: 400 q, = values 401 data = empty_data1D([q]) 402 elif len(values) == 2: 403 qx, qy = values 404 data = empty_data2D([qx], [qy]) 435 405 else: 436 data = empty_data1D([0.001]) # Data not used in ER/VR 406 print("use q or qx,qy") 407 sys.exit(1) 437 408 438 409 model_info = load_model_info(model_name) … … 442 413 for pair in sys.argv[3:] 443 414 for k, v in [pair.split('=')]) 444 if call == "ER_VR": 445 ER = call_ER(model_info, pars) 446 VR = call_VR(model_info, pars) 447 print(ER, VR) 448 else: 449 Iq = calculator(**pars) 450 print(Iq[0]) 415 Iq = calculator(**pars) 416 print(Iq[0]) 451 417 452 418 if __name__ == "__main__": -
sasmodels/model_test.py
r74e9b5f r304c775 59 59 from . import core 60 60 from .core import list_models, load_model_info, build_model 61 from .direct_model import call_kernel, call_ ER, call_VR61 from .direct_model import call_kernel, call_Fq 62 62 from .exception import annotate_exception 63 63 from .modelinfo import expand_pars … … 215 215 ({}, [(0.1, 0.1)]*2, [None]*2), 216 216 # test that ER/VR will run if they exist 217 ({}, 'ER', None), 218 ({}, 'VR', None), 217 ({}, 0.1, None, None, None, None, None), 219 218 ] 220 219 tests = smoke_tests … … 288 287 # type: (KernelModel, TestCondition) -> None 289 288 """Run a single test case.""" 290 user_pars, x, y = test 289 user_pars, x, y = test[:3] 291 290 pars = expand_pars(self.info.parameters, user_pars) 292 291 invalid = invalid_pars(self.info.parameters, pars) … … 301 300 self.assertEqual(len(y), len(x)) 302 301 303 if x[0] == 'ER': 304 actual = np.array([call_ER(model.info, pars)]) 305 elif x[0] == 'VR': 306 actual = np.array([call_VR(model.info, pars)]) 307 elif isinstance(x[0], tuple): 302 if isinstance(x[0], tuple): 308 303 qx, qy = zip(*x) 309 304 q_vectors = [np.array(qx), np.array(qy)] 310 kernel = model.make_kernel(q_vectors)311 actual = call_kernel(kernel, pars)312 305 else: 313 306 q_vectors = [np.array(x)] 314 kernel = model.make_kernel(q_vectors) 307 308 kernel = model.make_kernel(q_vectors) 309 if len(test) == 3: 315 310 actual = call_kernel(kernel, pars) 316 317 self.assertTrue(len(actual) > 0) 318 self.assertEqual(len(y), len(actual)) 319 320 for xi, yi, actual_yi in zip(x, y, actual): 311 self._check_vectors(x, y, actual, 'I') 312 return actual 313 else: 314 y1 = y 315 y2 = test[3] if not isinstance(test[3], list) else [test[3]] 316 F1, F2, R_eff, volume, volume_ratio = call_Fq(kernel, pars) 317 if F1 is not None: # F1 is none for models with Iq instead of Fq 318 self._check_vectors(x, y1, F1, 'F') 319 self._check_vectors(x, y2, F2, 'F^2') 320 self._check_scalar(test[4], R_eff, 'R_eff') 321 self._check_scalar(test[5], volume, 'volume') 322 self._check_scalar(test[6], volume_ratio, 'form:shell ratio') 323 return F2 324 325 def _check_scalar(self, target, actual, name): 326 if target is None: 327 # smoke test --- make sure it runs and produces a value 328 self.assertTrue(not np.isnan(actual), 329 'invalid %s: %s' % (name, actual)) 330 elif np.isnan(target): 331 # make sure nans match 332 self.assertTrue(np.isnan(actual), 333 '%s: expected:%s; actual:%s' 334 % (name, target, actual)) 335 else: 336 # is_near does not work for infinite values, so also test 337 # for exact values. 338 self.assertTrue(target == actual or is_near(target, actual, 5), 339 '%s: expected:%s; actual:%s' 340 % (name, target, actual)) 341 342 def _check_vectors(self, x, target, actual, name='I'): 343 self.assertTrue(len(actual) > 0, 344 '%s(...) expected return'%name) 345 if target is None: 346 return 347 self.assertEqual(len(target), len(actual), 348 '%s(...) returned wrong length'%name) 349 for xi, yi, actual_yi in zip(x, target, actual): 321 350 if yi is None: 322 351 # smoke test --- make sure it runs and produces a value 323 352 self.assertTrue(not np.isnan(actual_yi), 324 'invalid f(%s): %s' % (xi, actual_yi))353 'invalid %s(%s): %s' % (name, xi, actual_yi)) 325 354 elif np.isnan(yi): 355 # make sure nans match 326 356 self.assertTrue(np.isnan(actual_yi), 327 ' f(%s): expected:%s; actual:%s'328 % ( xi, yi, actual_yi))357 '%s(%s): expected:%s; actual:%s' 358 % (name, xi, yi, actual_yi)) 329 359 else: 330 360 # is_near does not work for infinite values, so also test 331 # for exact values. Note that this will not361 # for exact values. 332 362 self.assertTrue(yi == actual_yi or is_near(yi, actual_yi, 5), 333 'f(%s); expected:%s; actual:%s' 334 % (xi, yi, actual_yi)) 335 return actual 363 '%s(%s); expected:%s; actual:%s' 364 % (name, xi, yi, actual_yi)) 336 365 337 366 return ModelTestCase … … 345 374 invalid = [] 346 375 for par in sorted(pars.keys()): 376 # special handling of R_eff mode, which is not a usual parameter 377 if par == 'radius_effective_type': 378 continue 347 379 parts = par.split('_pd') 348 380 if len(parts) > 1 and parts[1] not in ("", "_n", "nsigma", "type"): -
sasmodels/models/_spherepy.py
rca4444f r304c775 71 71 return 1.333333333333333 * pi * radius ** 3 72 72 73 def effective_radius(mode, radius): 74 return radius 75 73 76 def Iq(q, sld, sld_solvent, radius): 74 77 #print "q",q … … 105 108 sesans.vectorized = True # sesans accepts an array of z values 106 109 107 def ER(radius):108 return radius109 110 # VR defaults to 1.0111 112 110 demo = dict(scale=1, background=0, 113 111 sld=6, sld_solvent=1, -
sasmodels/models/core_shell_bicelle_elliptical.py
ree60aa7 r304c775 184 184 185 185 tests = [ 186 [{'radius': 30.0, 'x_core': 3.0,187 'thick_rim': 8.0, 'thick_face': 14.0, 'length': 50.0}, 'ER', 1],188 [{'radius': 30.0, 'x_core': 3.0,189 'thick_rim': 8.0, 'thick_face': 14.0, 'length': 50.0}, 'VR', 1],186 #[{'radius': 30.0, 'x_core': 3.0, 187 # 'thick_rim': 8.0, 'thick_face': 14.0, 'length': 50.0}, 'ER', 1], 188 #[{'radius': 30.0, 'x_core': 3.0, 189 # 'thick_rim': 8.0, 'thick_face': 14.0, 'length': 50.0}, 'VR', 1], 190 190 191 191 [{'radius': 30.0, 'x_core': 3.0, -
sasmodels/models/core_shell_bicelle_elliptical_belt_rough.py
ree60aa7 r304c775 186 186 187 187 tests = [ 188 [{'radius': 30.0, 'x_core': 3.0, 'thick_rim':8.0, 'thick_face':14.0, 'length':50.0}, 'ER', 1],189 [{'radius': 30.0, 'x_core': 3.0, 'thick_rim':8.0, 'thick_face':14.0, 'length':50.0}, 'VR', 1],188 #[{'radius': 30.0, 'x_core': 3.0, 'thick_rim':8.0, 'thick_face':14.0, 'length':50.0}, 'ER', 1], 189 #[{'radius': 30.0, 'x_core': 3.0, 'thick_rim':8.0, 'thick_face':14.0, 'length':50.0}, 'VR', 1], 190 190 191 191 [{'radius': 30.0, 'x_core': 3.0, 'thick_rim':8.0, 'thick_face':14.0, 'length':50.0, -
sasmodels/models/core_shell_sphere.py
ree60aa7 r304c775 96 96 97 97 tests = [ 98 # [{'radius': 20.0, 'thickness': 10.0}, 'ER', 30.0],98 [{'radius': 20.0, 'thickness': 10.0}, 0.1, None, None, 30.0, 4.*pi/3*30**3, 1.0], 99 99 100 100 # The SasView test result was 0.00169, with a background of 0.001 -
sasmodels/models/cylinder.py
ree60aa7 r304c775 167 167 phi_pd=10, phi_pd_n=5) 168 168 169 # pylint: disable=bad-whitespace, line-too-long 169 170 qx, qy = 0.2 * np.cos(2.5), 0.2 * np.sin(2.5) 170 171 # After redefinition of angles, find new tests values. Was 10 10 in old coords … … 180 181 ] 181 182 del qx, qy # not necessary to delete, but cleaner 183 184 # Default radius and length 185 radius, length = parameters[2][2], parameters[3][2] 186 tests.extend([ 187 ({'radius_effective_type': 0}, 0.1, None, None, 0., pi*radius**2*length, 1.0), 188 ({'radius_effective_type': 1}, 0.1, None, None, (0.75*radius**2*length)**(1./3.), None, None), 189 ({'radius_effective_type': 2}, 0.1, None, None, radius, None, None), 190 ({'radius_effective_type': 3}, 0.1, None, None, length/2., None, None), 191 ({'radius_effective_type': 4}, 0.1, None, None, min(radius, length/2.), None, None), 192 ({'radius_effective_type': 5}, 0.1, None, None, max(radius, length/2.), None, None), 193 ({'radius_effective_type': 6}, 0.1, None, None, np.sqrt(4*radius**2 + length**2)/2., None, None), 194 ]) 195 del radius, length 196 # pylint: enable=bad-whitespace, line-too-long 197 182 198 # ADDED by: RKH ON: 18Mar2016 renamed sld's etc -
sasmodels/models/dab.py
r2d81cfe r304c775 74 74 return pars 75 75 76 # ER defaults to 1.077 78 # VR defaults to 1.079 80 76 demo = dict(scale=1, background=0, cor_length=50) -
sasmodels/models/gaussian_peak.py
r2d81cfe r304c775 50 50 """ 51 51 52 # VR defaults to 1.053 54 52 def random(): 55 53 peak_pos = 10**np.random.uniform(-3, -1) -
sasmodels/models/hardsphere.py
r71b751d r304c775 162 162 return pars 163 163 164 # ER defaults to 0.0165 # VR defaults to 1.0166 167 164 demo = dict(radius_effective=200, volfraction=0.2, 168 165 radius_effective_pd=0.1, radius_effective_pd_n=40) -
sasmodels/models/hayter_msa.py
r2d81cfe r304c775 89 89 return 1.0; 90 90 """ 91 # ER defaults to 0.092 # VR defaults to 1.093 91 94 92 def random(): -
sasmodels/models/hollow_cylinder.py
ree60aa7 r304c775 69 69 * **Last Reviewed by:** Paul Butler **Date:** September 06, 2018 70 70 """ 71 from __future__ import division 71 72 72 73 import numpy as np … … 132 133 qx = q*cos(pi/6.0) 133 134 qy = q*sin(pi/6.0) 135 radius = parameters[0][2] 136 thickness = parameters[1][2] 137 length = parameters[2][2] 134 138 # Parameters for unit tests 135 139 tests = [ 136 140 [{}, 0.00005, 1764.926], 137 # [{}, 'VR', 0.55555556], 141 [{}, 0.1, None, None, 142 (3./4*(radius+thickness)**2*length)**(1./3), # R_eff from volume 143 pi*((radius+thickness)**2-radius**2)*length, # shell volume 144 (radius+thickness)**2/((radius+thickness)**2 - radius**2), # form:shell ratio 145 ], 138 146 [{}, 0.001, 1756.76], 139 147 [{}, (qx, qy), 2.36885476192], -
sasmodels/models/lamellar.py
r2d81cfe r304c775 95 95 return pars 96 96 97 # ER defaults to 0.098 # VR defaults to 1.099 100 97 demo = dict(scale=1, background=0, 101 98 sld=6, sld_solvent=1, -
sasmodels/models/lamellar_hg.py
r2d81cfe r304c775 109 109 return pars 110 110 111 # ER defaults to 0.0112 # VR defaults to 1.0113 114 111 demo = dict(scale=1, background=0, 115 112 length_tail=15, length_head=10, -
sasmodels/models/lamellar_hg_stack_caille.py
r2d81cfe r304c775 122 122 """ 123 123 124 # ER defaults to 0.0125 # VR defaults to 1.0126 127 124 def random(): 128 125 total_thickness = 10**np.random.uniform(2, 4.7) -
sasmodels/models/lamellar_stack_caille.py
r2d81cfe r304c775 120 120 """ 121 121 122 # ER defaults to 0.0123 # VR defaults to 1.0124 125 122 demo = dict(scale=1, background=0, 126 123 thickness=67., Nlayers=3.75, d_spacing=200., -
sasmodels/models/lamellar_stack_paracrystal.py
r2d81cfe r304c775 147 147 return pars 148 148 149 # ER defaults to 0.0150 # VR defaults to 1.0151 152 149 demo = dict(scale=1, background=0, 153 150 thickness=33, Nlayers=20, d_spacing=250, sigma_d=0.2, -
sasmodels/models/sphere.py
ree60aa7 r304c775 83 83 "radius": 120., "radius_pd": 0.2, "radius_pd_n":45}, 84 84 0.2, 0.228843], 85 # [{"radius": 120., "radius_pd": 0.2, "radius_pd_n":45}, "ER", 120.],86 # [{"radius": 120., "radius_pd": 0.2, "radius_pd_n":45}, "VR", 1.],85 [{"radius": 120., "radius_pd": 0.2, "radius_pd_n":45}, 86 0.1, None, None, 120., None, 1.0], 87 87 ] -
sasmodels/models/squarewell.py
r2d81cfe r304c775 130 130 """ 131 131 132 # ER defaults to 0.0133 # VR defaults to 1.0134 135 132 def random(): 136 133 pars = dict( -
sasmodels/models/stickyhardsphere.py
r2d81cfe r304c775 182 182 """ 183 183 184 # ER defaults to 0.0185 # VR defaults to 1.0186 187 184 demo = dict(radius_effective=200, volfraction=0.2, perturb=0.05, 188 185 stickiness=0.2, radius_effective_pd=0.1, radius_effective_pd_n=40) -
sasmodels/models/vesicle.py
ree60aa7 r304c775 128 128 [{}, 0.100600200401, 1.77063682331], 129 129 [{}, 0.5, 0.00355351388906], 130 # [{}, 'ER', 130.], 131 # [{}, 'VR', 0.54483386436], 130 [{}, 0.1, None, None, 130., None, 1./0.54483386436], # R_eff, form:shell 132 131 ]
Note: See TracChangeset
for help on using the changeset viewer.