Changes in / [bef029d:5da1ac8] in sasmodels
- Files:
-
- 3 added
- 3 deleted
- 28 edited
Legend:
- Unmodified
- Added
- Removed
-
.travis.yml
rce8c388 r947a61e 24 24 packages: opencl-headers 25 25 before_install: 26 - if [[ $encrypted_cb04388797b6_iv ]]; then openssl aes-256-cbc -K $encrypted_cb04388797b6_key -iv $encrypted_cb04388797b6_iv27 -in .travis/travis_rsa.enc -out .travis/travis_rsa -d ; fi;26 - openssl aes-256-cbc -K $encrypted_fe6026add10a_key -iv $encrypted_fe6026add10a_iv 27 -in .travis/travis_rsa.enc -out .travis/travis_rsa -d 28 28 - echo $TRAVIS_OS_NAME 29 29 - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh … … 46 46 - echo -e "Host danse.chem.utk.edu\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config 47 47 deploy: 48 skip_cleanup: true49 provider: script50 script: "/bin/sh -ex ./deploy.sh"51 on:52 branch: master48 skip_cleanup: true 49 provider: script 50 script: /bin/sh -ex ./deploy.sh 51 on: 52 branch: master 53 53 notifications: 54 54 slack: -
deploy.sh
r9d1e3e4 rd9d77b0 1 if [[ $encrypted_cb04388797b6_iv ]] 2 then 3 eval "$(ssh-agent -s)" 4 chmod 600 .travis/travis_rsa 5 ssh-add .travis/travis_rsa 6 git remote add deploy git@danse.chem.utk.edu:/home/git/sasmodels 7 git push deploy master 8 fi 1 eval "$(ssh-agent -s)" 2 chmod 600 .travis/travis_rsa 3 ssh-add .travis/travis_rsa 4 git remote add deploy git@danse.chem.utk.edu:/home/git/sasmodels 5 git push deploy master -
doc/conf.py
r30b60d2 r8ae8532 211 211 #latex_preamble = '' 212 212 LATEX_PREAMBLE=r""" 213 \newcommand{\lt}{<}214 \newcommand{\gt}{>}215 213 \renewcommand{\AA}{\text{\r{A}}} % Allow \AA in math mode 216 214 \usepackage[utf8]{inputenc} % Allow unicode symbols in text -
doc/guide/magnetism/magnetism.rst
r990d8df r990d8df 16 16 17 17 .. figure:: 18 mag_img/mag_vector. png18 mag_img/mag_vector.bmp 19 19 20 20 The magnetic scattering length density is then … … 36 36 37 37 .. figure:: 38 mag_img/M_angles_pic. png38 mag_img/M_angles_pic.bmp 39 39 40 40 If the angles of the $Q$ vector and the spin-axis $x'$ to the $x$ - axis are -
doc/guide/plugin.rst
r30b60d2 r870a2f4 117 117 Models that do not conform to these requirements will *never* be incorporated 118 118 into the built-in library. 119 120 More complete documentation for the sasmodels package can be found at 121 `<http://www.sasview.org/sasmodels>`_. In particular, 122 `<http://www.sasview.org/sasmodels/api/generate.html#module-sasmodels.generate>`_ 123 describes the structure of a model. 119 124 120 125 … … 608 613 609 614 sas_gamma(x): 610 Gamma function sas_gamma\ $(x) = \Gamma(x)$.615 Gamma function $\text{sas_gamma}(x) = \Gamma(x)$. 611 616 612 617 The standard math function, tgamma(x) is unstable for $x < 1$ … … 618 623 sas_erf(x), sas_erfc(x): 619 624 Error function 620 sas_erf\ $(x) = \frac{2}{\sqrt\pi}\int_0^x e^{-t^2}\,dt$625 $\text{sas_erf}(x) = \frac{2}{\sqrt\pi}\int_0^x e^{-t^2}\,dt$ 621 626 and complementary error function 622 sas_erfc\ $(x) = \frac{2}{\sqrt\pi}\int_x^{\infty} e^{-t^2}\,dt$.627 $\text{sas_erfc}(x) = \frac{2}{\sqrt\pi}\int_x^{\infty} e^{-t^2}\,dt$. 623 628 624 629 The standard math functions erf(x) and erfc(x) are slower and broken … … 629 634 630 635 sas_J0(x): 631 Bessel function of the first kind sas_J0\ $(x)=J_0(x)$ where636 Bessel function of the first kind $\text{sas_J0}(x)=J_0(x)$ where 632 637 $J_0(x) = \frac{1}{\pi}\int_0^\pi \cos(x\sin(\tau))\,d\tau$. 633 638 … … 638 643 639 644 sas_J1(x): 640 Bessel function of the first kind sas_J1\ $(x)=J_1(x)$ where645 Bessel function of the first kind $\text{sas_J1}(x)=J_1(x)$ where 641 646 $J_1(x) = \frac{1}{\pi}\int_0^\pi \cos(\tau - x\sin(\tau))\,d\tau$. 642 647 … … 647 652 648 653 sas_JN(n, x): 649 Bessel function of the first kind and integer order $n$ ,650 sas_JN\ $(n, x)=J_n(x)$ where654 Bessel function of the first kind and integer order $n$: 655 $\text{sas_JN}(n, x)=J_n(x)$ where 651 656 $J_n(x) = \frac{1}{\pi}\int_0^\pi \cos(n\tau - x\sin(\tau))\,d\tau$. 652 If $n$ = 0 or 1, it uses sas_J0( $x$) or sas_J1($x$), respectively.657 If $n$ = 0 or 1, it uses sas_J0(x) or sas_J1(x), respectively. 653 658 654 659 The standard math function jn(n, x) is not available on all platforms. … … 658 663 659 664 sas_Si(x): 660 Sine integral Si\ $(x) = \int_0^x \tfrac{\sin t}{t}\,dt$.665 Sine integral $\text{Si}(x) = \int_0^x \tfrac{\sin t}{t}\,dt$. 661 666 662 667 This function uses Taylor series for small and large arguments: … … 683 688 sas_3j1x_x(x): 684 689 Spherical Bessel form 685 sph_j1c\ $(x) = 3 j_1(x)/x = 3 (\sin(x) - x \cos(x))/x^3$,690 $\text{sph_j1c}(x) = 3 j_1(x)/x = 3 (\sin(x) - x \cos(x))/x^3$, 686 691 with a limiting value of 1 at $x=0$, where $j_1(x)$ is the spherical 687 692 Bessel function of the first kind and first order. … … 694 699 695 700 sas_2J1x_x(x): 696 Bessel form sas_J1c\ $(x) = 2 J_1(x)/x$, with a limiting value701 Bessel form $\text{sas_J1c}(x) = 2 J_1(x)/x$, with a limiting value 697 702 of 1 at $x=0$, where $J_1(x)$ is the Bessel function of first kind 698 703 and first order. -
doc/guide/resolution.rst
r30b60d2 rf8a2baa 212 212 elliptical Gaussian distribution. The $A$ is a normalization factor. 213 213 214 .. figure:: resolution_2d_rotation. png214 .. figure:: resolution_2d_rotation.gif 215 215 216 216 Coordinate axis rotation for 2D resolution calculation. -
doc/rst_prolog
r30b60d2 ra0fb06a 1 1 .. Set up some substitutions to make life easier... 2 .. Remove |biggamma|, etc. when they are no longer needed. 2 3 4 5 .. |alpha| unicode:: U+03B1 6 .. |beta| unicode:: U+03B2 7 .. |gamma| unicode:: U+03B3 8 .. |delta| unicode:: U+03B4 9 .. |epsilon| unicode:: U+03B5 10 .. |zeta| unicode:: U+03B6 11 .. |eta| unicode:: U+03B7 12 .. |theta| unicode:: U+03B8 13 .. |iota| unicode:: U+03B9 14 .. |kappa| unicode:: U+03BA 15 .. |lambda| unicode:: U+03BB 16 .. |mu| unicode:: U+03BC 17 .. |nu| unicode:: U+03BD 18 .. |xi| unicode:: U+03BE 19 .. |omicron| unicode:: U+03BF 20 .. |pi| unicode:: U+03C0 21 .. |rho| unicode:: U+03C1 22 .. |sigma| unicode:: U+03C3 23 .. |tau| unicode:: U+03C4 24 .. |upsilon| unicode:: U+03C5 25 .. |phi| unicode:: U+03C6 26 .. |chi| unicode:: U+03C7 27 .. |psi| unicode:: U+03C8 28 .. |omega| unicode:: U+03C9 29 30 31 .. |biggamma| unicode:: U+0393 32 .. |bigdelta| unicode:: U+0394 33 .. |bigzeta| unicode:: U+039E 34 .. |bigpsi| unicode:: U+03A8 35 .. |bigphi| unicode:: U+03A6 36 .. |bigsigma| unicode:: U+03A3 37 .. |Gamma| unicode:: U+0393 38 .. |Delta| unicode:: U+0394 39 .. |Zeta| unicode:: U+039E 40 .. |Psi| unicode:: U+03A8 41 42 43 .. |drho| replace:: |Delta|\ |rho| 3 44 .. |Ang| unicode:: U+212B 4 45 .. |Ang^-1| replace:: |Ang|\ :sup:`-1` … … 16 57 .. |cm^-3| replace:: cm\ :sup:`-3` 17 58 .. |sr^-1| replace:: sr\ :sup:`-1` 59 .. |P0| replace:: P\ :sub:`0`\ 60 .. |A2| replace:: A\ :sub:`2`\ 61 62 63 .. |equiv| unicode:: U+2261 64 .. |noteql| unicode:: U+2260 65 .. |TM| unicode:: U+2122 66 18 67 19 68 .. |cdot| unicode:: U+00B7 -
sasmodels/compare.py
r765eb0e rd9ec8f9 88 88 -magnetic/-nonmagnetic* suppress magnetism 89 89 -accuracy=Low accuracy of the resolution calculation Low, Mid, High, Xhigh 90 -neval=1 sets the number of evals for more accurate timing91 90 92 91 === precision options === … … 1014 1013 'magnetic', 'nonmagnetic', 1015 1014 'accuracy=', 1016 'neval=', # for timing...1017 1015 1018 1016 # Precision options … … 1020 1018 'half', 'fast', 'single', 'double', 'single!', 'double!', 'quad!', 1021 1019 'sasview', # TODO: remove sasview 3.x support 1020 'timing=', 1022 1021 1023 1022 # Output options … … 1069 1068 1070 1069 # Plug in values given in demo 1071 if use_demo and model_info.demo:1070 if use_demo: 1072 1071 pars.update(model_info.demo) 1073 1072 return pars -
sasmodels/core.py
r60335cc rbb39b4a 10 10 11 11 import os 12 import re13 12 from os.path import basename, dirname, join as joinpath 14 13 from glob import glob … … 22 21 from . import kernelpy 23 22 from . import kerneldll 24 from . import custom25 23 26 24 if os.environ.get("SAS_OPENCL", "").lower() == "none": … … 32 30 except Exception: 33 31 HAVE_OPENCL = False 34 35 CUSTOM_MODEL_PATH = os.environ.get('SAS_MODELPATH', "")36 if CUSTOM_MODEL_PATH == "":37 path = joinpath(os.path.expanduser("~"), ".sasmodels", "custom_models")38 if not os.path.isdir(path):39 os.makedirs(path)40 CUSTOM_MODEL_PATH = path41 32 42 33 try: … … 134 125 dtype=dtype, platform=platform) 135 126 136 def load_model_info(model_string): 127 128 def load_model_info(model_name): 137 129 # type: (str) -> modelinfo.ModelInfo 138 130 """ 139 131 Load a model definition given the model name. 140 132 141 *model_string* is the name of the model, or perhaps a model expression 142 such as sphere*cylinder or sphere+cylinder. Use '@' for a structure 143 factor product, e.g. sphere@hardsphere. Custom models can be specified by 144 prefixing the model name with 'custom.', e.g. 'custom.MyModel+sphere'. 133 *model_name* is the name of the model, or perhaps a model expression 134 such as sphere*hardsphere or sphere+cylinder. 145 135 146 136 This returns a handle to the module defining the model. This can be 147 137 used with functions in generate to build the docs or extract model info. 148 138 """ 149 if '@' in model_string: 150 parts = model_string.split('@') 151 if len(parts) != 2: 152 raise ValueError("Use P@S to apply a structure factor S to model P") 153 P_info, Q_info = [load_model_info(part) for part in parts] 139 parts = model_name.split('+') 140 if len(parts) > 1: 141 model_info_list = [load_model_info(p) for p in parts] 142 return mixture.make_mixture_info(model_info_list) 143 144 parts = model_name.split('*') 145 if len(parts) > 1: 146 if len(parts) > 2: 147 raise ValueError("use P*S to apply structure factor S to model P") 148 P_info, Q_info = [load_model_info(p) for p in parts] 154 149 return product.make_product_info(P_info, Q_info) 155 150 156 product_parts = [] 157 addition_parts = [] 158 159 addition_parts_names = model_string.split('+') 160 if len(addition_parts_names) >= 2: 161 addition_parts = [load_model_info(part) for part in addition_parts_names] 162 elif len(addition_parts_names) == 1: 163 product_parts_names = model_string.split('*') 164 if len(product_parts_names) >= 2: 165 product_parts = [load_model_info(part) for part in product_parts_names] 166 elif len(product_parts_names) == 1: 167 if "custom." in product_parts_names[0]: 168 # Extract ModelName from "custom.ModelName" 169 pattern = "custom.([A-Za-z0-9_-]+)" 170 result = re.match(pattern, product_parts_names[0]) 171 if result is None: 172 raise ValueError("Model name in invalid format: " + product_parts_names[0]) 173 model_name = result.group(1) 174 # Use ModelName to find the path to the custom model file 175 model_path = joinpath(CUSTOM_MODEL_PATH, model_name + ".py") 176 if not os.path.isfile(model_path): 177 raise ValueError("The model file {} doesn't exist".format(model_path)) 178 kernel_module = custom.load_custom_kernel_module(model_path) 179 return modelinfo.make_model_info(kernel_module) 180 # Model is a core model 181 kernel_module = generate.load_kernel_module(product_parts_names[0]) 182 return modelinfo.make_model_info(kernel_module) 183 184 model = None 185 if len(product_parts) > 1: 186 model = mixture.make_mixture_info(product_parts, operation='*') 187 if len(addition_parts) > 1: 188 if model is not None: 189 addition_parts.append(model) 190 model = mixture.make_mixture_info(addition_parts, operation='+') 191 return model 151 kernel_module = generate.load_kernel_module(model_name) 152 return modelinfo.make_model_info(kernel_module) 192 153 193 154 -
sasmodels/generate.py
r30b60d2 r573ffab 210 210 211 211 # Conversion from units defined in the parameter table for each model 212 # to units displayed in the sphinx documentation. 212 # to units displayed in the sphinx documentation. 213 213 # This section associates the unit with the macro to use to produce the LaTex 214 214 # code. The macro itself needs to be defined in sasmodels/doc/rst_prolog. … … 216 216 # NOTE: there is an RST_PROLOG at the end of this file which is NOT 217 217 # used for the bundled documentation. Still as long as we are defining the macros 218 # in two places any new addition should define the macro in both places. 218 # in two places any new addition should define the macro in both places. 219 219 RST_UNITS = { 220 220 "Ang": "|Ang|", … … 898 898 .. |cm^-3| replace:: cm\ :sup:`-3` 899 899 .. |sr^-1| replace:: sr\ :sup:`-1` 900 .. |P0| replace:: P\ :sub:`0`\ 901 902 .. |equiv| unicode:: U+2261 903 .. |noteql| unicode:: U+2260 904 .. |TM| unicode:: U+2122 900 905 901 906 .. |cdot| unicode:: U+00B7 -
sasmodels/mixture.py
r765eb0e r6dc78e4 25 25 pass 26 26 27 def make_mixture_info(parts , operation='+'):27 def make_mixture_info(parts): 28 28 # type: (List[ModelInfo]) -> ModelInfo 29 29 """ 30 30 Create info block for mixture model. 31 31 """ 32 flatten = [] 33 for part in parts: 34 if part.composition and part.composition[0] == 'mixture': 35 flatten.extend(part.composition[1]) 36 else: 37 flatten.append(part) 38 parts = flatten 39 32 40 # Build new parameter list 33 41 combined_pars = [] 34 35 model_num = 0 36 all_parts = copy(parts) 37 is_flat = False 38 while not is_flat: 39 is_flat = True 40 for part in all_parts: 41 if part.composition and part.composition[0] == 'mixture' and \ 42 len(part.composition[1]) > 1: 43 all_parts += part.composition[1] 44 all_parts.remove(part) 45 is_flat = False 46 47 # When creating a mixture model that is a sum of product models (ie (1*2)+(3*4)) 48 # the parameters for models 1 & 2 will be prefixed with A & B respectively, 49 # but so will the parameters for models 3 & 4. We need to rename models 3 & 4 50 # so that they are prefixed with C & D to avoid overlap of parameter names. 51 used_prefixes = [] 52 for part in parts: 53 i = 0 54 if part.composition and part.composition[0] == 'mixture': 55 npars_list = [info.parameters.npars for info in part.composition[1]] 56 for npars in npars_list: 57 # List of params of one of the constituent models of part 58 submodel_pars = part.parameters.kernel_parameters[i:i+npars] 59 # Prefix of the constituent model 60 prefix = submodel_pars[0].name[0] 61 if prefix not in used_prefixes: # Haven't seen this prefix so far 62 used_prefixes.append(prefix) 63 i += npars 64 continue 65 while prefix in used_prefixes: 66 # This prefix has been already used, so change it to the 67 # next letter that hasn't been used 68 prefix = chr(ord(prefix) + 1) 69 used_prefixes.append(prefix) 70 prefix += "_" 71 # Update the parameters of this constituent model to use the 72 # new prefix 73 for par in submodel_pars: 74 par.id = prefix + par.id[2:] 75 par.name = prefix + par.name[2:] 76 if par.length_control is not None: 77 par.length_control = prefix + par.length_control[2:] 78 i += npars 79 80 for part in parts: 42 demo = {} 43 for k, part in enumerate(parts): 81 44 # Parameter prefix per model, A_, B_, ... 82 45 # Note that prefix must also be applied to id and length_control 83 46 # to support vector parameters 84 prefix = '' 85 if not part.composition: 86 # Model isn't a composition model, so it's parameters don't have a 87 # a prefix. Add the next available prefix 88 prefix = chr(ord('A')+len(used_prefixes)) 89 used_prefixes.append(prefix) 90 prefix += '_' 91 92 if operation == '+': 93 # If model is a sum model, each constituent model gets its own scale parameter 94 scale_prefix = prefix 95 if prefix == '' and part.operation == '*': 96 # `part` is a composition product model. Find the prefixes of 97 # it's parameters to form a new prefix for the scale, eg: 98 # a model with A*B*C will have ABC_scale 99 sub_prefixes = [] 100 for param in part.parameters.kernel_parameters: 101 # Prefix of constituent model 102 sub_prefix = param.id.split('_')[0] 103 if sub_prefix not in sub_prefixes: 104 sub_prefixes.append(sub_prefix) 105 # Concatenate sub_prefixes to form prefix for the scale 106 scale_prefix = ''.join(sub_prefixes) + '_' 107 scale = Parameter(scale_prefix + 'scale', default=1.0, 108 description="model intensity for " + part.name) 109 combined_pars.append(scale) 47 prefix = chr(ord('A')+k) + '_' 48 scale = Parameter(prefix+'scale', default=1.0, 49 description="model intensity for " + part.name) 50 combined_pars.append(scale) 110 51 for p in part.parameters.kernel_parameters: 111 52 p = copy(p) … … 115 56 p.length_control = prefix + p.length_control 116 57 combined_pars.append(p) 58 demo.update((prefix+k, v) for k, v in part.demo.items() 59 if k != "background") 60 #print("pars",combined_pars) 117 61 parameters = ParameterTable(combined_pars) 118 62 parameters.max_pd = sum(part.parameters.max_pd for part in parts) 119 63 120 def random():121 combined_pars = {}122 for k, part in enumerate(parts):123 prefix = chr(ord('A')+k) + '_'124 pars = part.random()125 combined_pars.update((prefix+k, v) for k, v in pars.items())126 return combined_pars127 128 64 model_info = ModelInfo() 129 model_info.id = operation.join(part.id for part in parts) 130 model_info.operation = operation 131 model_info.name = '(' + operation.join(part.name for part in parts) + ')' 65 model_info.id = '+'.join(part.id for part in parts) 66 model_info.name = ' + '.join(part.name for part in parts) 132 67 model_info.filename = None 133 68 model_info.title = 'Mixture model with ' + model_info.name … … 136 71 model_info.category = "custom" 137 72 model_info.parameters = parameters 138 model_info.random = random139 73 #model_info.single = any(part['single'] for part in parts) 140 74 model_info.structure_factor = False … … 145 79 # Remember the component info blocks so we can build the model 146 80 model_info.composition = ('mixture', parts) 81 model_info.demo = demo 147 82 return model_info 148 83 … … 153 88 self.info = model_info 154 89 self.parts = parts 155 self.dtype = parts[0].dtype156 90 157 91 def make_kernel(self, q_vectors): … … 182 116 self.kernels = kernels 183 117 self.dtype = self.kernels[0].dtype 184 self.operation = model_info.operation185 118 self.results = [] # type: List[np.ndarray] 186 119 … … 191 124 # remember the parts for plotting later 192 125 self.results = [] # type: List[np.ndarray] 126 offset = 2 # skip scale & background 193 127 parts = MixtureParts(self.info, self.kernels, call_details, values) 194 128 for kernel, kernel_details, kernel_values in parts: 195 129 #print("calling kernel", kernel.info.name) 196 130 result = kernel(kernel_details, kernel_values, cutoff, magnetic) 197 result = np.array(result).astype(kernel.dtype) 198 # print(kernel.info.name, result) 199 if self.operation == '+': 200 total += result 201 elif self.operation == '*': 202 if np.all(total) == 0.0: 203 total = result 204 else: 205 total *= result 131 #print(kernel.info.name, result) 132 total += result 206 133 self.results.append(result) 207 134 … … 244 171 245 172 self.part_num += 1 246 self.par_index += info.parameters.npars 247 if self.model_info.operation == '+': 248 self.par_index += 1 # Account for each constituent model's scale param 173 self.par_index += info.parameters.npars + 1 249 174 self.mag_index += 3 * len(info.parameters.magnetism_index) 250 175 … … 257 182 # which includes the initial scale and background parameters. 258 183 # We want the index into the weight length/offset for each parameter. 259 # Exclude the initial scale and background, so subtract two. If we're 260 # building an addition model, each component has its own scale factor 261 # which we need to skip when constructing the details for the kernel, so 262 # add one, giving a net subtract one. 263 diff = 1 if self.model_info.operation == '+' else 2 264 index = slice(par_index - diff, par_index - diff + info.parameters.npars) 184 # Exclude the initial scale and background, so subtract two, but each 185 # component has its own scale factor which we need to skip when 186 # constructing the details for the kernel, so add one, giving a 187 # net subtract one. 188 index = slice(par_index - 1, par_index - 1 + info.parameters.npars) 265 189 length = full.length[index] 266 190 offset = full.offset[index] … … 272 196 def _part_values(self, info, par_index, mag_index): 273 197 # type: (ModelInfo, int, int) -> np.ndarray 274 # Set each constituent model's scale to 1 if this is a multiplication model 275 scale = self.values[par_index] if self.model_info.operation == '+' else 1.0 276 diff = 1 if self.model_info.operation == '+' else 0 # Skip scale if addition model 277 pars = self.values[par_index + diff:par_index + info.parameters.npars + diff] 198 #print(info.name, par_index, self.values[par_index:par_index + info.parameters.npars + 1]) 199 scale = self.values[par_index] 200 pars = self.values[par_index + 1:par_index + info.parameters.npars + 1] 278 201 nmagnetic = len(info.parameters.magnetism_index) 279 202 if nmagnetic: -
sasmodels/model_test.py
r65314f7 rbedb9b0 201 201 ({}, 'VR', None), 202 202 ] 203 tests = smoke_tests 204 if self.info.tests is not None: 205 tests += self.info.tests 203 204 tests = smoke_tests + self.info.tests 206 205 try: 207 206 model = build_model(self.info, dtype=self.dtype, … … 372 371 stream.writeln(traceback.format_exc()) 373 372 return 373 374 374 # Run the test suite 375 375 suite.run(result) -
sasmodels/modelinfo.py
r65314f7 r0bdddc2 727 727 models when the model is first called, not when the model is loaded. 728 728 """ 729 if hasattr(kernel_module, "model_info"):730 # Custom sum/multi models731 return kernel_module.model_info732 729 info = ModelInfo() 733 730 #print("make parameter table", kernel_module.parameters) -
sasmodels/models/binary_hard_sphere.py
r30b60d2 r8f04da4 23 23 :nowrap: 24 24 25 \begin{align *}25 \begin{align} 26 26 x &= \frac{(\phi_2 / \phi)\alpha^3}{(1-(\phi_2/\phi) + (\phi_2/\phi) 27 27 \alpha^3)} \\ 28 28 \phi &= \phi_1 + \phi_2 = \text{total volume fraction} \\ 29 29 \alpha &= R_1/R_2 = \text{size ratio} 30 \end{align *}30 \end{align} 31 31 32 32 The 2D scattering intensity is the same as 1D, regardless of the orientation of -
sasmodels/models/core_shell_bicelle.py
r30b60d2 ra151caa 41 41 42 42 I(Q,\alpha) = \frac{\text{scale}}{V_t} \cdot 43 F(Q,\alpha)^2 \cdotsin(\alpha) + \text{background}43 F(Q,\alpha)^2.sin(\alpha) + \text{background} 44 44 45 45 where 46 46 47 47 .. math:: 48 :nowrap:49 48 50 \begin{align *}49 \begin{align} 51 50 F(Q,\alpha) = &\bigg[ 52 51 (\rho_c - \rho_f) V_c \frac{2J_1(QRsin \alpha)}{QRsin\alpha}\frac{sin(QLcos\alpha/2)}{Q(L/2)cos\alpha} \\ … … 54 53 &+(\rho_r - \rho_s) V_t \frac{2J_1(Q(R+t_r)sin\alpha)}{Q(R+t_r)sin\alpha}\frac{sin(Q(L/2+t_f)cos\alpha)}{Q(L/2+t_f)cos\alpha} 55 54 \bigg] 56 \end{align *}55 \end{align} 57 56 58 57 where $V_t$ is the total volume of the bicelle, $V_c$ the volume of the core, -
sasmodels/models/core_shell_bicelle_elliptical.py
r30b60d2 r8f04da4 42 42 43 43 I(Q,\alpha,\psi) = \frac{\text{scale}}{V_t} \cdot 44 F(Q,\alpha, \psi)^2 \cdotsin(\alpha) + \text{background}44 F(Q,\alpha, \psi)^2.sin(\alpha) + \text{background} 45 45 46 where a numerical integration of $F(Q,\alpha, \psi)^2 \cdotsin(\alpha)$ is carried out over \alpha and \psi for:46 where a numerical integration of $F(Q,\alpha, \psi)^2.sin(\alpha)$ is carried out over \alpha and \psi for: 47 47 48 48 .. math:: 49 :nowrap:50 49 51 \begin{align*}50 \begin{align} 52 51 F(Q,\alpha,\psi) = &\bigg[ 53 52 (\rho_c - \rho_f) V_c \frac{2J_1(QR'sin \alpha)}{QR'sin\alpha}\frac{sin(QLcos\alpha/2)}{Q(L/2)cos\alpha} \\ … … 55 54 &+(\rho_r - \rho_s) V_t \frac{2J_1(Q(R'+t_r)sin\alpha)}{Q(R'+t_r)sin\alpha}\frac{sin(Q(L/2+t_f)cos\alpha)}{Q(L/2+t_f)cos\alpha} 56 55 \bigg] 57 \end{align *}56 \end{align} 58 57 59 58 where -
sasmodels/models/core_shell_ellipsoid.py
r30b60d2 r9f6823b 44 44 45 45 .. math:: 46 :nowrap: 47 48 \begin{align*} 46 \begin{align} 49 47 F(q,\alpha) = &f(q,radius\_equat\_core,radius\_equat\_core.x\_core,\alpha) \\ 50 48 &+ f(q,radius\_equat\_core + thick\_shell,radius\_equat\_core.x\_core + thick\_shell.x\_polar\_shell,\alpha) 51 \end{align *}49 \end{align} 52 50 53 51 where -
sasmodels/models/fractal_core_shell.py
r8f04da4 r8f04da4 31 31 $\rho_{solv}$ are the scattering length densities of the core, shell, and 32 32 solvent respectively, $r_c$ and $r_s$ are the radius of the core and the radius 33 of the whole particle respectively, $D_f$ is the fractal dimension, and $\xi$the33 of the whole particle respectively, $D_f$ is the fractal dimension, and |xi| the 34 34 correlation length. 35 35 -
sasmodels/models/hollow_rectangular_prism.py
r30b60d2 r8f04da4 31 31 :nowrap: 32 32 33 \begin{align *}33 \begin{align} 34 34 A_{P\Delta}(q) & = A B C 35 35 \left[\frac{\sin \bigl( q \frac{C}{2} \cos\theta \bigr)} … … 47 47 \left[ \frac{\sin \bigl[ q \bigl(\frac{B}{2}-\Delta\bigr) \sin\theta \cos\phi \bigr]} 48 48 {q \bigl(\frac{B}{2}-\Delta\bigr) \sin\theta \cos\phi} \right] 49 \end{align *}49 \end{align} 50 50 51 51 where $A$, $B$ and $C$ are the external sides of the parallelepiped fulfilling -
sasmodels/models/multilayer_vesicle.py
r870a2f4 r870a2f4 33 33 .. math:: 34 34 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 } i35 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 37 37 38 38 $\phi$ is the volume fraction of particles, $V(r)$ is the volume of a sphere -
sasmodels/models/parallelepiped.py
r30b60d2 r8f04da4 20 20 Parallelepiped with the corresponding definition of sides. 21 21 22 The three dimensions of the parallelepiped (strictly here a cuboid) may be 23 given in *any* size order. To avoid multiple fit solutions, especially 24 with Monte-Carlo fit methods, it may be advisable to restrict their ranges. 25 There may be a number of closely similar "best fits", so some trial and 26 error, or fixing of some dimensions at expected values, may help. 22 .. note:: 23 24 The three dimensions of the parallelepiped (strictly here a cuboid) may be given in 25 $any$ size order. To avoid multiple fit solutions, especially 26 with Monte-Carlo fit methods, it may be advisable to restrict their ranges. There may 27 be a number of closely similar "best fits", so some trial and error, or fixing of some 28 dimensions at expected values, may help. 27 29 28 30 The 1D scattering intensity $I(q)$ is calculated as: -
sasmodels/models/rpa.py
r30b60d2 r4f9e288 30 30 These case numbers are different from those in the NIST SANS package! 31 31 32 The models are based on the papers by Akcasu *et al.*and by33 Hammouda assuming the polymer follows Gaussian statistics such32 The models are based on the papers by Akcasu et al. [#Akcasu]_ and by 33 Hammouda [#Hammouda]_ assuming the polymer follows Gaussian statistics such 34 34 that $R_g^2 = n b^2/6$ where $b$ is the statistical segment length and $n$ is 35 35 the number of statistical segment lengths. A nice tutorial on how these are 36 36 constructed and implemented can be found in chapters 28 and 39 of Boualem 37 Hammouda's 'SANS Toolbox' .37 Hammouda's 'SANS Toolbox'[#toolbox]_. 38 38 39 39 In brief the macroscopic cross sections are derived from the general forms … … 49 49 are calculated with respect to component D).** So the scattering contrast 50 50 for a C/D blend = [SLD(component C) - SLD(component D)]\ :sup:`2`. 51 * Depending on which case is being used, the number of fitting parameters can 51 * Depending on which case is being used, the number of fitting parameters can 52 52 vary. 53 53 … … 57 57 component are obtained from other methods and held fixed while The *scale* 58 58 parameter should be held equal to unity. 59 * The variables are normally the segment lengths ($b_a$, $b_b$, 60 etc.) and $\chi$ parameters ($K_{ab}$, $K_{ac}$, etc). 59 * The variables are normally the segment lengths (b\ :sub:`a`, b\ :sub:`b`, 60 etc) and $\chi$ parameters (K\ :sub:`ab`, K\ :sub:`ac`, etc). 61 61 62 62 63 References 63 64 ---------- 64 65 65 A Z Akcasu, R Klein and B Hammouda, *Macromolecules*, 26 (1993) 4136. 66 67 B. Hammouda, *Advances in Polymer Science* 106 (1993) 87. 68 69 B. Hammouda, *SANS Toolbox* 70 https://www.ncnr.nist.gov/staff/hammouda/the_sans_toolbox.pdf. 66 .. [#Akcasu] A Z Akcasu, R Klein and B Hammouda, *Macromolecules*, 26 (1993) 67 4136. 68 .. [#Hammouda] B. Hammouda, *Advances in Polymer Science* 106 (1993) 87. 69 .. [#toolbox] https://www.ncnr.nist.gov/staff/hammouda/the_sans_toolbox.pdf 71 70 72 71 Authorship and Verification -
sasmodels/models/spherical_sld.py
r2ad5d30 r63a7fe8 18 18 Interface shapes are as follows:: 19 19 20 0: erf( $\nu z$)21 1: Rpow( $z^\nu$)22 2: Lpow( $z^\nu$)23 3: Rexp( $-\nu z$)24 4: Lexp( $-\nu z$)20 0: erf(|nu|*z) 21 1: Rpow(z^|nu|) 22 2: Lpow(z^|nu|) 23 3: Rexp(-|nu|z) 24 4: Lexp(-|nu|z) 25 25 26 26 Definition -
sasmodels/models/star_polymer.py
r5da1ac8 r5da1ac8 7 7 emanating from a common central (in the case of this model) point. It is 8 8 derived as a special case of on the Benoit model for general branched 9 polymers\ [#CITBenoit]_ as also used by Richter *et al.*\ [#CITRichter]_9 polymers\ [#CITBenoit]_ as also used by Richter ''et. al.''\ [#CITRichter]_ 10 10 11 11 For a star with $f$ arms the scattering intensity $I(q)$ is calculated as -
sasmodels/models/surface_fractal.py
r30b60d2 r48462b0 9 9 10 10 .. math:: 11 :nowrap:12 11 13 \begin{align*}14 12 I(q) &= \text{scale} \times P(q)S(q) + \text{background} \\ 15 13 P(q) &= F(qR)^2 \\ … … 17 15 S(q) &= \Gamma(5-D_S)\xi^{\,5-D_S}\left[1+(q\xi)^2 \right]^{-(5-D_S)/2} 18 16 \sin\left[-(5-D_S) \tan^{-1}(q\xi) \right] q^{-1} \\ 19 \text{scale} &= \text{scale factor}\, N V^1(\rho_\text{particle} - \rho_\text{solvent})^2 \\17 \text{scale} &= \text{scale_factor}\, N V^2(\rho_\text{particle} - \rho_\text{solvent})^2 \\ 20 18 V &= \frac{4}{3}\pi R^3 21 \end{align*}22 19 23 20 where $R$ is the radius of the building block, $D_S$ is the **surface** fractal -
sasmodels/product.py
r765eb0e r8f04da4 68 68 translate_name = dict((old.id, new.id) for old, new 69 69 in zip(s_pars.kernel_parameters[1:], s_list)) 70 demo = {} 71 demo.update(p_info.demo.items()) 72 demo.update((translate_name[k], v) for k, v in s_info.demo.items() 73 if k not in ("background", "scale") and not k.startswith(ER_ID)) 70 74 combined_pars = p_pars.kernel_parameters + s_list 71 75 parameters = ParameterTable(combined_pars) 72 76 parameters.max_pd = p_pars.max_pd + s_pars.max_pd 73 def random():74 combined_pars = p_info.random()75 s_names = set(par.id for par in s_pars.kernel_parameters[1:])76 s = s_info.random()77 combined_pars.update((translate_name[k], v)78 for k, v in s_info.random().items()79 if k in s_names)80 return combined_pars81 77 82 78 model_info = ModelInfo() 83 model_info.id = ' @'.join((p_id, s_id))84 model_info.name = ' @'.join((p_name, s_name))79 model_info.id = '*'.join((p_id, s_id)) 80 model_info.name = '*'.join((p_name, s_name)) 85 81 model_info.filename = None 86 82 model_info.title = 'Product of %s and %s'%(p_name, s_name) … … 89 85 model_info.category = "custom" 90 86 model_info.parameters = parameters 91 model_info.random = random92 87 #model_info.single = p_info.single and s_info.single 93 88 model_info.structure_factor = False … … 100 95 # TODO: delegate random to p_info, s_info 101 96 #model_info.random = lambda: {} 102 103 ## Show the parameter table 97 model_info.demo = demo 98 99 ## Show the parameter table with the demo values 104 100 #from .compare import get_pars, parlist 105 101 #print("==== %s ====="%model_info.name) 106 #values = get_pars(model_info )102 #values = get_pars(model_info, use_demo=True) 107 103 #print(parlist(model_info, values, is2d=True)) 108 104 return model_info … … 130 126 self.P = P 131 127 self.S = S 132 self.dtype = P.dtype133 128 134 129 def make_kernel(self, q_vectors): -
sasmodels/sasview_model.py
rbcdd6c9 r724257c 120 120 else: 121 121 model_info = modelinfo.make_model_info(kernel_module) 122 model = make_model_from_info(model_info)122 model = _make_model_from_info(model_info) 123 123 model.timestamp = getmtime(path) 124 124 … … 142 142 143 143 144 def make_model_from_info(model_info):145 # type: (ModelInfo) -> SasviewModelType146 """147 Convert *model_info* into a SasView model wrapper.148 """149 def __init__(self, multiplicity=None):150 SasviewModel.__init__(self, multiplicity=multiplicity)151 attrs = _generate_model_attributes(model_info)152 attrs['__init__'] = __init__153 attrs['filename'] = model_info.filename154 ConstructedModel = type(model_info.name, (SasviewModel,), attrs) # type: SasviewModelType155 return ConstructedModel156 157 158 144 def _make_standard_model(name): 159 145 # type: (str) -> SasviewModelType … … 167 153 kernel_module = generate.load_kernel_module(name) 168 154 model_info = modelinfo.make_model_info(kernel_module) 169 return make_model_from_info(model_info)170 171 155 return _make_model_from_info(model_info) 156 157 172 158 def _register_old_models(): 173 159 # type: () -> None … … 201 187 model_info = product.make_product_info(form_factor._model_info, 202 188 structure_factor._model_info) 203 ConstructedModel = make_model_from_info(model_info)189 ConstructedModel = _make_model_from_info(model_info) 204 190 return ConstructedModel() 205 191 192 def _make_model_from_info(model_info): 193 # type: (ModelInfo) -> SasviewModelType 194 """ 195 Convert *model_info* into a SasView model wrapper. 196 """ 197 def __init__(self, multiplicity=None): 198 SasviewModel.__init__(self, multiplicity=multiplicity) 199 attrs = _generate_model_attributes(model_info) 200 attrs['__init__'] = __init__ 201 attrs['filename'] = model_info.filename 202 ConstructedModel = type(model_info.name, (SasviewModel,), attrs) # type: SasviewModelType 203 return ConstructedModel 206 204 207 205 def _generate_model_attributes(model_info): … … 605 603 if hasattr(self._model_info, "composition") \ 606 604 and self._model_info.composition is not None: 607 p_model = make_model_from_info(self._model_info.composition[1][0])()608 s_model = make_model_from_info(self._model_info.composition[1][1])()605 p_model = _make_model_from_info(self._model_info.composition[1][0])() 606 s_model = _make_model_from_info(self._model_info.composition[1][1])() 609 607 return p_model, s_model 610 608
Note: See TracChangeset
for help on using the changeset viewer.