Changeset 9c44b7b in sasmodels
- Timestamp:
- Mar 9, 2017 6:42:21 PM (8 years ago)
- Branches:
- master, core_shell_microgels, costrafo411, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
- Children:
- 3a45c2c
- Parents:
- 68f45cb (diff), 0011ecc (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. - Location:
- sasmodels
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/compare.py
rd504bcd rf72d70a 321 321 if '*' in name: 322 322 name = name.split('*')[0] 323 324 # Suppress magnetism for python models (not yet implemented) 325 if callable(model_info.Iq): 326 pars.update(suppress_magnetism(pars)) 323 327 324 328 if name == 'barbell': -
sasmodels/compare_many.py
r424fe00 rf72d70a 106 106 header = ('\n"Model","%s","Count","%d","Dimension","%s"' 107 107 % (name, N, "2D" if is_2d else "1D")) 108 if not mono: header += ',"Cutoff",%g'%(cutoff,) 108 if not mono: 109 header += ',"Cutoff",%g'%(cutoff,) 109 110 print(header) 110 111 … … 161 162 max_diff = [0] 162 163 for k in range(N): 163 print(" %s %d"%(name, k), file=sys.stderr)164 print("Model %s %d"%(name, k+1), file=sys.stderr) 164 165 seed = np.random.randint(1e6) 165 166 pars_i = randomize_pars(model_info, pars, seed) 166 167 constrain_pars(model_info, pars_i) 167 constrain_new_to_old(model_info, pars_i) 168 if 'sasview' in (base, comp): 169 constrain_new_to_old(model_info, pars_i) 168 170 if mono: 169 171 pars_i = suppress_pd(pars_i) … … 187 189 Print the command usage string. 188 190 """ 189 print("usage: compare_many.py MODEL COUNT (1dNQ|2dNQ) (CUTOFF|mono) (single|double|quad)") 191 print("usage: compare_many.py MODEL COUNT (1dNQ|2dNQ) (CUTOFF|mono) (single|double|quad)", 192 file=sys.stderr) 190 193 191 194 … … 204 207 print("""\ 205 208 206 MODEL is the model name of the model or "all" for all the models 207 in alphabetical order. 209 MODEL is the model name of the model or one of the model types listed in 210 sasmodels.core.list_models (all, py, c, double, single, opencl, 1d, 2d, 211 nonmagnetic, magnetic). Model types can be combined, such as 2d+single. 208 212 209 213 COUNT is the number of randomly generated parameter sets to try. A value … … 220 224 below the cutoff will be ignored. Use "mono" for monodisperse models. The 221 225 choice of polydisperse parameters, and the number of points in the distribution 222 is set in compare.py defaults for each model. 226 is set in compare.py defaults for each model. Polydispersity is given in the 227 "demo" attribute of each model. 223 228 224 229 PRECISION is the floating point precision to use for comparisons. If two 225 precisions are given, then compare one to the other, ignoring sasview. 230 precisions are given, then compare one to the other. Precision is one of 231 fast, single, double for GPU or single!, double!, quad! for DLL. If no 232 precision is given, then use single and double! respectively. 226 233 227 234 Available models: … … 233 240 Main program. 234 241 """ 235 if len(argv) not in ( 5, 6):242 if len(argv) not in (3, 4, 5, 6): 236 243 print_help() 237 244 return 238 245 239 model = argv[0] 240 if not (model in MODELS) and (model != "all"): 241 print('Bad model %s. Use "all" or one of:'%model) 246 target = argv[0] 247 try: 248 model_list = [target] if target in MODELS else core.list_models(target) 249 except ValueError: 250 print('Bad model %s. Use model type or one of:' % target, file=sys.stderr) 242 251 print_models() 252 print('model types: all, py, c, double, single, opencl, 1d, 2d, nonmagnetic, magnetic') 243 253 return 244 254 try: … … 247 257 assert argv[2][1] == 'd' 248 258 Nq = int(argv[2][2:]) 249 mono = argv[3] == 'mono'259 mono = len(argv) <= 3 or argv[3] == 'mono' 250 260 cutoff = float(argv[3]) if not mono else 0 251 base = argv[4] 252 comp = argv[5] if len(argv) > 5 else " sasview"261 base = argv[4] if len(argv) > 4 else "single" 262 comp = argv[5] if len(argv) > 5 else "double!" 253 263 except Exception: 254 264 traceback.print_exc() … … 258 268 data, index = make_data({'qmax':1.0, 'is2d':is2D, 'nq':Nq, 'res':0., 259 269 'accuracy': 'Low', 'view':'log', 'zero': False}) 260 model_list = [model] if model != "all" else MODELS261 270 for model in model_list: 262 271 compare_instance(model, data, index, N=count, mono=mono, -
sasmodels/core.py
r52e9a45 r5124c969 69 69 * magnetic: models with an sld 70 70 * nommagnetic: models without an sld 71 """ 72 if kind and kind not in KINDS: 71 72 For multiple conditions, combine with plus. For example, *c+single+2d* 73 would return all oriented models implemented in C which can be computed 74 accurately with single precision arithmetic. 75 """ 76 if kind and any(k not in KINDS for k in kind.split('+')): 73 77 raise ValueError("kind not in " + ", ".join(KINDS)) 74 78 files = sorted(glob(joinpath(generate.MODEL_PATH, "[a-zA-Z]*.py"))) 75 79 available_models = [basename(f)[:-3] for f in files] 76 selected = [name for name in available_models if _matches(name, kind)] 80 if kind and '+' in kind: 81 all_kinds = kind.split('+') 82 condition = lambda name: all(_matches(name, k) for k in all_kinds) 83 else: 84 condition = lambda name: _matches(name, kind) 85 selected = [name for name in available_models if condition(name)] 77 86 78 87 return selected -
sasmodels/model_test.py
r479d0f3 r598857b 97 97 is_py = callable(model_info.Iq) 98 98 99 # Some OpenCL drivers seem to be flaky, and are not producing the 100 # expected result. Since we don't have known test values yet for 101 # all of our models, we are instead going to compare the results 102 # for the 'smoke test' (that is, evaluation at q=0.1 for the default 103 # parameters just to see that the model runs to completion) between 104 # the OpenCL and the DLL. To do this, we define a 'stash' which is 105 # shared between OpenCL and DLL tests. This is just a list. If the 106 # list is empty (which it will be when DLL runs, if the DLL runs 107 # first), then the results are appended to the list. If the list 108 # is not empty (which it will be when OpenCL runs second), the results 109 # are compared to the results stored in the first element of the list. 110 # This is a horrible stateful hack which only makes sense because the 111 # test suite is thrown away after being run once. 112 stash = [] 113 99 114 if is_py: # kernel implemented in python 100 115 test_name = "Model: %s, Kernel: python"%model_name … … 103 118 test_method_name, 104 119 platform="dll", # so that 105 dtype="double") 120 dtype="double", 121 stash=stash) 106 122 suite.addTest(test) 107 123 else: # kernel implemented in C 124 125 # test using dll if desired 126 if 'dll' in loaders or not core.HAVE_OPENCL: 127 test_name = "Model: %s, Kernel: dll"%model_name 128 test_method_name = "test_%s_dll" % model_info.id 129 test = ModelTestCase(test_name, model_info, 130 test_method_name, 131 platform="dll", 132 dtype="double", 133 stash=stash) 134 suite.addTest(test) 135 108 136 # test using opencl if desired and available 109 137 if 'opencl' in loaders and core.HAVE_OPENCL: … … 116 144 test = ModelTestCase(test_name, model_info, 117 145 test_method_name, 118 platform="ocl", dtype=None) 146 platform="ocl", dtype=None, 147 stash=stash) 119 148 #print("defining", test_name) 120 suite.addTest(test)121 122 # test using dll if desired123 if 'dll' in loaders or not core.HAVE_OPENCL:124 test_name = "Model: %s, Kernel: dll"%model_name125 test_method_name = "test_%s_dll" % model_info.id126 test = ModelTestCase(test_name, model_info,127 test_method_name,128 platform="dll",129 dtype="double")130 149 suite.addTest(test) 131 150 … … 144 163 """ 145 164 def __init__(self, test_name, model_info, test_method_name, 146 platform, dtype ):147 # type: (str, ModelInfo, str, str, DType ) -> None165 platform, dtype, stash): 166 # type: (str, ModelInfo, str, str, DType, List[Any]) -> None 148 167 self.test_name = test_name 149 168 self.info = model_info 150 169 self.platform = platform 151 170 self.dtype = dtype 171 self.stash = stash # container for the results of the first run 152 172 153 173 setattr(self, test_method_name, self.run_all) … … 167 187 #({}, (0.0, 0.0), None), 168 188 # test vector form 169 ({}, [0. 1]*2, [None]*2),189 ({}, [0.001, 0.01, 0.1], [None]*3), 170 190 ({}, [(0.1, 0.1)]*2, [None]*2), 171 191 # test that ER/VR will run if they exist … … 174 194 ] 175 195 176 tests = s elf.info.tests196 tests = smoke_tests + self.info.tests 177 197 try: 178 198 model = build_model(self.info, dtype=self.dtype, 179 199 platform=self.platform) 180 for test in smoke_tests + tests: 181 self.run_one(model, test) 182 183 if not tests and self.platform == "dll": 184 ## Uncomment the following to make forgetting the test 185 ## values an error. Only do so for the "dll" tests 186 ## to reduce noise from both opencl and dll, and because 187 ## python kernels use platform="dll". 188 #raise Exception("No test cases provided") 189 pass 200 results = [self.run_one(model, test) for test in tests] 201 if self.stash: 202 for test, target, actual in zip(tests, self.stash[0], results): 203 assert np.all(abs(target-actual) < 5e-5*abs(actual)),\ 204 "GPU/CPU comparison expected %s but got %s for %s"%(target, actual, test[0]) 205 else: 206 self.stash.append(results) 207 208 # Check for missing tests. Only do so for the "dll" tests 209 # to reduce noise from both opencl and dll, and because 210 # python kernels use platform="dll". 211 if self.platform == "dll": 212 missing = [] 213 ## Uncomment the following to require test cases 214 #missing = self._find_missing_tests() 215 if missing: 216 raise ValueError("Missing tests for "+", ".join(missing)) 190 217 191 218 except: 192 219 annotate_exception(self.test_name) 193 220 raise 221 222 def _find_missing_tests(self): 223 # type: () -> None 224 """make sure there are 1D, 2D, ER and VR tests as appropriate""" 225 model_has_VR = callable(self.info.VR) 226 model_has_ER = callable(self.info.ER) 227 model_has_1D = True 228 model_has_2D = any(p.type == 'orientation' 229 for p in self.info.parameters.kernel_parameters) 230 231 # Lists of tests that have a result that is not None 232 single = [test for test in self.info.tests 233 if not isinstance(test[2], list) and test[2] is not None] 234 tests_has_VR = any(test[1] == 'VR' for test in single) 235 tests_has_ER = any(test[1] == 'ER' for test in single) 236 tests_has_1D_single = any(isinstance(test[1], float) for test in single) 237 tests_has_2D_single = any(isinstance(test[1], tuple) for test in single) 238 239 multiple = [test for test in self.info.tests 240 if isinstance(test[2], list) 241 and not all(result is None for result in test[2])] 242 tests_has_1D_multiple = any(isinstance(test[1][0], float) 243 for test in multiple) 244 tests_has_2D_multiple = any(isinstance(test[1][0], tuple) 245 for test in multiple) 246 247 missing = [] 248 if model_has_VR and not tests_has_VR: 249 missing.append("VR") 250 if model_has_ER and not tests_has_ER: 251 missing.append("ER") 252 if model_has_1D and not (tests_has_1D_single or tests_has_1D_multiple): 253 missing.append("1D") 254 if model_has_2D and not (tests_has_2D_single or tests_has_2D_multiple): 255 missing.append("2D") 256 257 return missing 194 258 195 259 def run_one(self, model, test): … … 207 271 208 272 if x[0] == 'ER': 209 actual = [call_ER(model.info, pars)]273 actual = np.array([call_ER(model.info, pars)]) 210 274 elif x[0] == 'VR': 211 actual = [call_VR(model.info, pars)]275 actual = np.array([call_VR(model.info, pars)]) 212 276 elif isinstance(x[0], tuple): 213 277 qx, qy = zip(*x) … … 238 302 'f(%s); expected:%s; actual:%s' 239 303 % (xi, yi, actual_yi)) 304 return actual 240 305 241 306 return ModelTestCase -
sasmodels/modelinfo.py
rf88e248 r9c44b7b 734 734 info.docs = kernel_module.__doc__ 735 735 info.category = getattr(kernel_module, 'category', None) 736 info.single = getattr(kernel_module, 'single', True)737 info.opencl = getattr(kernel_module, 'opencl', True)738 736 info.structure_factor = getattr(kernel_module, 'structure_factor', False) 739 737 info.profile_axes = getattr(kernel_module, 'profile_axes', ['x', 'y']) … … 749 747 info.profile = getattr(kernel_module, 'profile', None) # type: ignore 750 748 info.sesans = getattr(kernel_module, 'sesans', None) # type: ignore 749 # Default single and opencl to True for C models. Python models have callable Iq. 750 info.opencl = getattr(kernel_module, 'opencl', not callable(info.Iq)) 751 info.single = getattr(kernel_module, 'single', not callable(info.Iq)) 751 752 752 753 # multiplicity info -
sasmodels/conversion_table.py
r790b16bb r0c2da4b 549 549 "radius": "core_radius", 550 550 "sld_solvent": "core_sld", 551 "n_ pairs": "n_pairs",551 "n_shells": "n_pairs", 552 552 "thick_shell": "s_thickness", 553 553 "sld": "shell_sld", -
sasmodels/models/multilayer_vesicle.c
rc3ccaec rec1d4bc 1 static 2 double multilayer_vesicle_kernel(double q, 1 static double 2 form_volume(double radius, 3 double thick_shell, 4 double thick_solvent, 5 double fp_n_shells) 6 { 7 int n_shells = (int)(fp_n_shells + 0.5); 8 double R_N = radius + n_shells*(thick_shell+thick_solvent) - thick_solvent; 9 return M_4PI_3*cube(R_N); 10 } 11 12 static double 13 multilayer_vesicle_kernel(double q, 3 14 double volfraction, 4 15 double radius, … … 7 18 double sld_solvent, 8 19 double sld, 9 int n_ pairs)20 int n_shells) 10 21 { 11 22 //calculate with a loop, two shells at a time … … 29 40 30 41 //do 2 layers at a time 31 ii += 1;42 ii++; 32 43 33 } while(ii <= n_ pairs-1); //change to make 0 < n_pairs < 2 correspond to44 } while(ii <= n_shells-1); //change to make 0 < n_shells < 2 correspond to 34 45 //unilamellar vesicles (C. Glinka, 11/24/03) 35 46 36 fval *= volfraction*1.0e-4*fval/voli; 37 38 return(fval); 47 return 1.0e-4*volfraction*fval*fval; // Volume normalization happens in caller 39 48 } 40 49 41 static 42 doubleIq(double q,50 static double 51 Iq(double q, 43 52 double volfraction, 44 53 double radius, … … 47 56 double sld_solvent, 48 57 double sld, 49 double fp_n_ pairs)58 double fp_n_shells) 50 59 { 51 int n_ pairs = (int)(fp_n_pairs + 0.5);60 int n_shells = (int)(fp_n_shells + 0.5); 52 61 return multilayer_vesicle_kernel(q, 53 62 volfraction, … … 57 66 sld_solvent, 58 67 sld, 59 n_ pairs);68 n_shells); 60 69 } 61 70 -
sasmodels/models/multilayer_vesicle.py
rc3ccaec r68f45cb 5 5 This model is a trivial extension of the core_shell_sphere function to include 6 6 *N* shells where the core is filled with solvent and the shells are interleaved 7 with layers of solvent. For *N = 1*, this returns the same as the vesicle model,7 with layers of solvent. For $N = 1$, this returns the same as the vesicle model, 8 8 except for the normalisation, which here is to outermost volume. 9 9 The shell thicknessess and SLD are constant for all shells as expected for … … 19 19 20 20 .. math:: 21 P(q) = \text{scale} \cdot \frac{V_f}{V_t} F^2(q) + \text{background} 21 P(q) = \text{scale} \cdot \frac{\phi}{V(R_N)} F^2(q) + \text{background} 22 23 where 24 25 .. math:: 26 F(q) = (\rho_\text{shell}-\rho_\text{solv}) \sum_{i=1}^{N} \left[ 27 3V(r_i)\frac{\sin(qr_i) - qr_i\cos(qr_i)}{(qr_i)^3} 28 - 3V(R_i)\frac{\sin(qR_i) - qR_i\cos(qR_i)}{(qR_i)^3} 29 \right] 22 30 23 31 for 24 32 25 33 .. math:: 26 F(q) = (\rho_\text{shell}-\rho_\text{solv}) \sum_{i=1}^{n_\text{pairs}}27 \left[28 3V(R_i)\frac{\sin(qR_i)-qR_i\cos(qR_i)}{(qR_i)^3} \\29 - 3V(R_i+t_s)\frac{\sin(q(R_i+t_s))-q(R_i+t_s)\cos(q(R_i+t_s))}{(q(R_i+t_s))^3}30 \right]31 34 32 and 35 r_i &= r_c + (i-1)(t_s + t_w) && \text{ solvent radius before shell } i \\ 36 R_i &= r_i + t_s && \text{ shell radius for shell } i 33 37 34 .. math:: 35 R_i = r_c + (i-1)(t_s + t_w) 38 $\phi$ is the volume fraction of particles, $V(r)$ is the volume of a sphere 39 of radius $r$, $r_c$ is the radius of the core, $t_s$ is the thickness of 40 the shell, $t_w$ is the thickness of the solvent layer between the shells, 41 $\rho_\text{shell}$ is the scattering length density of a shell, and 42 $\rho_\text{solv}$ is the scattering length density of the solvent. 36 43 37 where $V_f$ is the volume fraction of particles, $V_t$ is the volume of the 38 whole particle, $V(r)$ is the volume of a sphere of radius $r$, $r_c$ is the 39 radius of the core, $\rho_\text{shell}$ is the scattering length density of a 40 shell, $\rho_\text{solv}$ is the scattering length density of the solvent. 44 The outer-most shell radius $R_N$ is used as the effective radius 45 for $P(Q)$ when $P(Q) * S(Q)$ is applied. 41 46 42 The outer most radius, $r_o = R_n + t_s$, is used for both the volume fraction 43 normalization and for the effective radius for *S(Q)* when $P(Q) * S(Q)$ 44 is applied. 47 For mixed systems in which some vesicles have 1 shell, some have 2, 48 etc., use polydispersity on $N$ to model the data. For example, 49 create a file such as *shell_dist.txt* containing the relative portion 50 of each vesicle size:: 51 52 1 20 53 2 4 54 3 1 55 56 Turn on polydispersity and select an array distribution for the *n_shells* 57 parameter. Choose the above *shell_dist.txt* file, and the model will be 58 computed with 80% 1-shell vesicles, 16% 2-shell vesicles and 4% 59 3-shell vesicles. 45 60 46 61 The 2D scattering intensity is the same as 1D, regardless of the orientation … … 86 101 sld_solvent: solvent scattering length density 87 102 sld: shell scattering length density 88 n_ pairs:number of "shell plus solvent" layer pairs103 n_shells:number of "shell plus solvent" layer pairs 89 104 background: incoherent background 90 105 """ … … 95 110 parameters = [ 96 111 ["volfraction", "", 0.05, [0.0, 1], "", "volume fraction of vesicles"], 97 ["radius", "Ang", 60.0, [0.0, inf], " ", "radius of solvent filled core"],98 ["thick_shell", "Ang", 10.0, [0.0, inf], " ", "thickness of one shell"],99 ["thick_solvent", "Ang", 10.0, [0.0, inf], " ", "solvent thickness between shells"],112 ["radius", "Ang", 60.0, [0.0, inf], "volume", "radius of solvent filled core"], 113 ["thick_shell", "Ang", 10.0, [0.0, inf], "volume", "thickness of one shell"], 114 ["thick_solvent", "Ang", 10.0, [0.0, inf], "volume", "solvent thickness between shells"], 100 115 ["sld_solvent", "1e-6/Ang^2", 6.4, [-inf, inf], "sld", "solvent scattering length density"], 101 116 ["sld", "1e-6/Ang^2", 0.4, [-inf, inf], "sld", "Shell scattering length density"], 102 ["n_ pairs", "", 2.0, [1.0, inf], "", "Number of shell plus solvent layer pairs"],117 ["n_shells", "", 2.0, [1.0, inf], "volume", "Number of shell plus solvent layer pairs"], 103 118 ] 104 119 # pylint: enable=bad-whitespace, line-too-long 105 120 121 # TODO: proposed syntax for specifying which parameters can be polydisperse 122 #polydispersity = ["radius", "thick_shell"] 123 106 124 source = ["lib/sas_3j1x_x.c", "multilayer_vesicle.c"] 107 125 108 # TODO: the following line does nothing 109 polydispersity = ["radius", "n_pairs"] 126 def ER(radius, thick_shell, thick_solvent, n_shells): 127 n_shells = int(n_shells+0.5) 128 return radius + n_shells * (thick_shell + thick_solvent) - thick_solvent 110 129 111 130 demo = dict(scale=1, background=0, … … 116 135 sld_solvent=6.4, 117 136 sld=0.4, 118 n_ pairs=2.0)137 n_shells=2.0) 119 138 120 139 tests = [ … … 125 144 'sld_solvent': 6.4, 126 145 'sld': 0.4, 127 'n_ pairs': 2.0,146 'n_shells': 2.0, 128 147 'scale': 1.0, 129 148 'background': 0.001, … … 136 155 'sld_solvent': 6.4, 137 156 'sld': 0.4, 138 'n_ pairs': 2.0,157 'n_shells': 2.0, 139 158 'scale': 1.0, 140 159 'background': 0.001, -
sasmodels/product.py
r9951a86 rf88e248 45 45 # structure factor calculator. Structure factors should not 46 46 # have any magnetic parameters 47 assert(s_info.parameters.kernel_parameters[0].id == ER_ID) 48 assert(s_info.parameters.kernel_parameters[1].id == VF_ID) 49 assert(s_info.parameters.magnetism_index == []) 47 if not s_info.parameters.kernel_parameters[0].id == ER_ID: 48 raise TypeError("S needs %s as first parameter"%ER_ID) 49 if not s_info.parameters.kernel_parameters[1].id == VF_ID: 50 raise TypeError("S needs %s as second parameter"%VF_ID) 51 if not s_info.parameters.magnetism_index == []: 52 raise TypeError("S should not have SLD parameters") 50 53 p_id, p_name, p_pars = p_info.id, p_info.name, p_info.parameters 51 54 s_id, s_name, s_pars = s_info.id, s_info.name, s_info.parameters 52 p_set = set(p.id for p in p_pars.call_parameters) 53 s_set = set(p.id for p in s_pars.call_parameters) 54 55 if p_set & s_set: 56 # there is some overlap between the parameter names; tag the 57 # overlapping S parameters with name_S. 58 # Skip the first parameter of s, which is effective radius 59 s_list = [(suffix_parameter(par) if par.id in p_set else par) 60 for par in s_pars.kernel_parameters[1:]] 61 else: 62 # Skip the first parameter of s, which is effective radius 63 s_list = s_pars.kernel_parameters[1:] 55 56 # Create list of parameters for the combined model. Skip the first 57 # parameter of S, which we verified above is effective radius. If there 58 # are any names in P that overlap with those in S, modify the name in S 59 # to distinguish it. 60 p_set = set(p.id for p in p_pars.kernel_parameters) 61 s_list = [(_tag_parameter(par) if par.id in p_set else par) 62 for par in s_pars.kernel_parameters[1:]] 63 # Check if still a collision after renaming. This could happen if for 64 # example S has volfrac and P has both volfrac and volfrac_S. 65 if any(p.id in p_set for p in s_list): 66 raise TypeError("name collision: P has P.name and P.name_S while S has S.name") 67 64 68 translate_name = dict((old.id, new.id) for old, new 65 69 in zip(s_pars.kernel_parameters[1:], s_list)) 66 70 demo = {} 67 demo.update((k, v) for k, v in p_info.demo.items() 68 if k not in ("background", "scale")) 71 demo.update(p_info.demo.items()) 69 72 demo.update((translate_name[k], v) for k, v in s_info.demo.items() 70 73 if k not in ("background", "scale") and not k.startswith(ER_ID)) … … 90 93 # Remember the component info blocks so we can build the model 91 94 model_info.composition = ('product', [p_info, s_info]) 92 model_info.demo = {} 95 model_info.demo = demo 96 97 ## Show the parameter table with the demo values 98 #from .compare import get_pars, parlist 99 #print("==== %s ====="%model_info.name) 100 #values = get_pars(model_info, use_demo=True) 101 #print(parlist(model_info, values, is2d=True)) 93 102 return model_info 94 103 95 def suffix_parameter(par, suffix): 104 def _tag_parameter(par): 105 """ 106 Tag the parameter name with _S to indicate that the parameter comes from 107 the structure factor parameter set. This is only necessary if the 108 form factor model includes a parameter of the same name as a parameter 109 in the structure factor. 110 """ 96 111 par = copy(par) 97 par.name = par.name + " S" 112 # Protect against a vector parameter in S by appending the vector length 113 # to the renamed parameter. Note: haven't tested this since no existing 114 # structure factor models contain vector parameters. 115 vector_length = par.name[len(par.id):] 98 116 par.id = par.id + "_S" 117 par.name = par.id + vector_length 99 118 return par 100 119
Note: See TracChangeset
for help on using the changeset viewer.