Changes in / [bef029d:5da1ac8] in sasmodels


Ignore:
Files:
3 added
3 deleted
28 edited

Legend:

Unmodified
Added
Removed
  • .travis.yml

    rce8c388 r947a61e  
    2424    packages: opencl-headers 
    2525before_install: 
    26 - if [[ $encrypted_cb04388797b6_iv ]]; then openssl aes-256-cbc -K $encrypted_cb04388797b6_key -iv $encrypted_cb04388797b6_iv 
    27   -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 
    2828- echo $TRAVIS_OS_NAME 
    2929- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh 
     
    4646- echo -e "Host danse.chem.utk.edu\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config 
    4747deploy: 
    48   skip_cleanup: true 
    49   provider: script 
    50   script: "/bin/sh -ex ./deploy.sh" 
    51   on: 
    52     branch: master 
     48    skip_cleanup: true 
     49    provider: script 
     50    script: /bin/sh -ex ./deploy.sh 
     51    on: 
     52        branch: master 
    5353notifications: 
    5454  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 
     1eval "$(ssh-agent -s)" 
     2chmod 600 .travis/travis_rsa 
     3ssh-add .travis/travis_rsa 
     4git remote add deploy git@danse.chem.utk.edu:/home/git/sasmodels 
     5git push deploy master 
  • doc/conf.py

    r30b60d2 r8ae8532  
    211211#latex_preamble = '' 
    212212LATEX_PREAMBLE=r""" 
    213 \newcommand{\lt}{<} 
    214 \newcommand{\gt}{>} 
    215213\renewcommand{\AA}{\text{\r{A}}} % Allow \AA in math mode 
    216214\usepackage[utf8]{inputenc}      % Allow unicode symbols in text 
  • doc/guide/magnetism/magnetism.rst

    r990d8df r990d8df  
    1616 
    1717.. figure:: 
    18     mag_img/mag_vector.png 
     18    mag_img/mag_vector.bmp 
    1919 
    2020The magnetic scattering length density is then 
     
    3636 
    3737.. figure:: 
    38     mag_img/M_angles_pic.png 
     38    mag_img/M_angles_pic.bmp 
    3939 
    4040If the angles of the $Q$ vector and the spin-axis $x'$ to the $x$ - axis are 
  • doc/guide/plugin.rst

    r30b60d2 r870a2f4  
    117117Models that do not conform to these requirements will *never* be incorporated 
    118118into the built-in library. 
     119 
     120More 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>`_ 
     123describes the structure of a model. 
    119124 
    120125 
     
    608613 
    609614    sas_gamma(x): 
    610         Gamma function sas_gamma\ $(x) = \Gamma(x)$. 
     615        Gamma function $\text{sas_gamma}(x) = \Gamma(x)$. 
    611616 
    612617        The standard math function, tgamma(x) is unstable for $x < 1$ 
     
    618623    sas_erf(x), sas_erfc(x): 
    619624        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$ 
    621626        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$. 
    623628 
    624629        The standard math functions erf(x) and erfc(x) are slower and broken 
     
    629634 
    630635    sas_J0(x): 
    631         Bessel function of the first kind sas_J0\ $(x)=J_0(x)$ where 
     636        Bessel function of the first kind $\text{sas_J0}(x)=J_0(x)$ where 
    632637        $J_0(x) = \frac{1}{\pi}\int_0^\pi \cos(x\sin(\tau))\,d\tau$. 
    633638 
     
    638643 
    639644    sas_J1(x): 
    640         Bessel function of the first kind  sas_J1\ $(x)=J_1(x)$ where 
     645        Bessel function of the first kind  $\text{sas_J1}(x)=J_1(x)$ where 
    641646        $J_1(x) = \frac{1}{\pi}\int_0^\pi \cos(\tau - x\sin(\tau))\,d\tau$. 
    642647 
     
    647652 
    648653    sas_JN(n, x): 
    649         Bessel function of the first kind and integer order $n$, 
    650         sas_JN\ $(n, x) =J_n(x)$ where 
     654        Bessel function of the first kind and integer order $n$: 
     655        $\text{sas_JN}(n, x)=J_n(x)$ where 
    651656        $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. 
    653658 
    654659        The standard math function jn(n, x) is not available on all platforms. 
     
    658663 
    659664    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$. 
    661666 
    662667        This function uses Taylor series for small and large arguments: 
     
    683688    sas_3j1x_x(x): 
    684689        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$, 
    686691        with a limiting value of 1 at $x=0$, where $j_1(x)$ is the spherical 
    687692        Bessel function of the first kind and first order. 
     
    694699 
    695700    sas_2J1x_x(x): 
    696         Bessel form sas_J1c\ $(x) = 2 J_1(x)/x$, with a limiting value 
     701        Bessel form $\text{sas_J1c}(x) = 2 J_1(x)/x$, with a limiting value 
    697702        of 1 at $x=0$, where $J_1(x)$ is the Bessel function of first kind 
    698703        and first order. 
  • doc/guide/resolution.rst

    r30b60d2 rf8a2baa  
    212212elliptical Gaussian distribution. The $A$ is a normalization factor. 
    213213 
    214 .. figure:: resolution_2d_rotation.png 
     214.. figure:: resolution_2d_rotation.gif 
    215215 
    216216    Coordinate axis rotation for 2D resolution calculation. 
  • doc/rst_prolog

    r30b60d2 ra0fb06a  
    11.. Set up some substitutions to make life easier... 
     2.. Remove |biggamma|, etc. when they are no longer needed. 
    23 
     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| 
    344.. |Ang| unicode:: U+212B 
    445.. |Ang^-1| replace:: |Ang|\ :sup:`-1` 
     
    1657.. |cm^-3| replace:: cm\ :sup:`-3` 
    1758.. |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 
    1867 
    1968.. |cdot| unicode:: U+00B7 
  • sasmodels/compare.py

    r765eb0e rd9ec8f9  
    8888    -magnetic/-nonmagnetic* suppress magnetism 
    8989    -accuracy=Low accuracy of the resolution calculation Low, Mid, High, Xhigh 
    90     -neval=1 sets the number of evals for more accurate timing 
    9190 
    9291    === precision options === 
     
    10141013    'magnetic', 'nonmagnetic', 
    10151014    'accuracy=', 
    1016     'neval=',  # for timing... 
    10171015 
    10181016    # Precision options 
     
    10201018    'half', 'fast', 'single', 'double', 'single!', 'double!', 'quad!', 
    10211019    'sasview',  # TODO: remove sasview 3.x support 
     1020    'timing=', 
    10221021 
    10231022    # Output options 
     
    10691068 
    10701069    # Plug in values given in demo 
    1071     if use_demo and model_info.demo: 
     1070    if use_demo: 
    10721071        pars.update(model_info.demo) 
    10731072    return pars 
  • sasmodels/core.py

    r60335cc rbb39b4a  
    1010 
    1111import os 
    12 import re 
    1312from os.path import basename, dirname, join as joinpath 
    1413from glob import glob 
     
    2221from . import kernelpy 
    2322from . import kerneldll 
    24 from . import custom 
    2523 
    2624if os.environ.get("SAS_OPENCL", "").lower() == "none": 
     
    3230    except Exception: 
    3331        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 = path 
    4132 
    4233try: 
     
    134125                       dtype=dtype, platform=platform) 
    135126 
    136 def load_model_info(model_string): 
     127 
     128def load_model_info(model_name): 
    137129    # type: (str) -> modelinfo.ModelInfo 
    138130    """ 
    139131    Load a model definition given the model name. 
    140132 
    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. 
    145135 
    146136    This returns a handle to the module defining the model.  This can be 
    147137    used with functions in generate to build the docs or extract model info. 
    148138    """ 
    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] 
    154149        return product.make_product_info(P_info, Q_info) 
    155150 
    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) 
    192153 
    193154 
  • sasmodels/generate.py

    r30b60d2 r573ffab  
    210210 
    211211# 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.  
    213213# This section associates the unit with the macro to use to produce the LaTex 
    214214# code.  The macro itself needs to be defined in sasmodels/doc/rst_prolog. 
     
    216216# NOTE: there is an RST_PROLOG at the end of this file which is NOT 
    217217# 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.  
    219219RST_UNITS = { 
    220220    "Ang": "|Ang|", 
     
    898898.. |cm^-3| replace:: cm\ :sup:`-3` 
    899899.. |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 
    900905 
    901906.. |cdot| unicode:: U+00B7 
  • sasmodels/mixture.py

    r765eb0e r6dc78e4  
    2525    pass 
    2626 
    27 def make_mixture_info(parts, operation='+'): 
     27def make_mixture_info(parts): 
    2828    # type: (List[ModelInfo]) -> ModelInfo 
    2929    """ 
    3030    Create info block for mixture model. 
    3131    """ 
     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 
    3240    # Build new parameter list 
    3341    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): 
    8144        # Parameter prefix per model, A_, B_, ... 
    8245        # Note that prefix must also be applied to id and length_control 
    8346        # 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) 
    11051        for p in part.parameters.kernel_parameters: 
    11152            p = copy(p) 
     
    11556                p.length_control = prefix + p.length_control 
    11657            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) 
    11761    parameters = ParameterTable(combined_pars) 
    11862    parameters.max_pd = sum(part.parameters.max_pd for part in parts) 
    11963 
    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_pars 
    127  
    12864    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) 
    13267    model_info.filename = None 
    13368    model_info.title = 'Mixture model with ' + model_info.name 
     
    13671    model_info.category = "custom" 
    13772    model_info.parameters = parameters 
    138     model_info.random = random 
    13973    #model_info.single = any(part['single'] for part in parts) 
    14074    model_info.structure_factor = False 
     
    14579    # Remember the component info blocks so we can build the model 
    14680    model_info.composition = ('mixture', parts) 
     81    model_info.demo = demo 
    14782    return model_info 
    14883 
     
    15388        self.info = model_info 
    15489        self.parts = parts 
    155         self.dtype = parts[0].dtype 
    15690 
    15791    def make_kernel(self, q_vectors): 
     
    182116        self.kernels = kernels 
    183117        self.dtype = self.kernels[0].dtype 
    184         self.operation = model_info.operation 
    185118        self.results = []  # type: List[np.ndarray] 
    186119 
     
    191124        # remember the parts for plotting later 
    192125        self.results = []  # type: List[np.ndarray] 
     126        offset = 2 # skip scale & background 
    193127        parts = MixtureParts(self.info, self.kernels, call_details, values) 
    194128        for kernel, kernel_details, kernel_values in parts: 
    195129            #print("calling kernel", kernel.info.name) 
    196130            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 
    206133            self.results.append(result) 
    207134 
     
    244171 
    245172        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 
    249174        self.mag_index += 3 * len(info.parameters.magnetism_index) 
    250175 
     
    257182        # which includes the initial scale and background parameters. 
    258183        # 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) 
    265189        length = full.length[index] 
    266190        offset = full.offset[index] 
     
    272196    def _part_values(self, info, par_index, mag_index): 
    273197        # 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] 
    278201        nmagnetic = len(info.parameters.magnetism_index) 
    279202        if nmagnetic: 
  • sasmodels/model_test.py

    r65314f7 rbedb9b0  
    201201                ({}, 'VR', None), 
    202202                ] 
    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 
    206205            try: 
    207206                model = build_model(self.info, dtype=self.dtype, 
     
    372371        stream.writeln(traceback.format_exc()) 
    373372        return 
     373 
    374374    # Run the test suite 
    375375    suite.run(result) 
  • sasmodels/modelinfo.py

    r65314f7 r0bdddc2  
    727727    models when the model is first called, not when the model is loaded. 
    728728    """ 
    729     if hasattr(kernel_module, "model_info"): 
    730         # Custom sum/multi models 
    731         return kernel_module.model_info 
    732729    info = ModelInfo() 
    733730    #print("make parameter table", kernel_module.parameters) 
  • sasmodels/models/binary_hard_sphere.py

    r30b60d2 r8f04da4  
    2323    :nowrap: 
    2424 
    25     \begin{align*} 
     25    \begin{align} 
    2626    x &= \frac{(\phi_2 / \phi)\alpha^3}{(1-(\phi_2/\phi) + (\phi_2/\phi) 
    2727    \alpha^3)} \\ 
    2828    \phi &= \phi_1 + \phi_2 = \text{total volume fraction} \\ 
    2929    \alpha &= R_1/R_2 = \text{size ratio} 
    30     \end{align*} 
     30    \end{align} 
    3131 
    3232The 2D scattering intensity is the same as 1D, regardless of the orientation of 
  • sasmodels/models/core_shell_bicelle.py

    r30b60d2 ra151caa  
    4141 
    4242    I(Q,\alpha) = \frac{\text{scale}}{V_t} \cdot 
    43         F(Q,\alpha)^2 \cdot sin(\alpha) + \text{background} 
     43        F(Q,\alpha)^2.sin(\alpha) + \text{background} 
    4444 
    4545where 
    4646 
    4747.. math:: 
    48     :nowrap: 
    4948 
    50     \begin{align*} 
     49    \begin{align} 
    5150    F(Q,\alpha) = &\bigg[ 
    5251    (\rho_c - \rho_f) V_c \frac{2J_1(QRsin \alpha)}{QRsin\alpha}\frac{sin(QLcos\alpha/2)}{Q(L/2)cos\alpha} \\ 
     
    5453    &+(\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} 
    5554    \bigg] 
    56     \end{align*} 
     55    \end{align} 
    5756 
    5857where $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  
    4242 
    4343    I(Q,\alpha,\psi) = \frac{\text{scale}}{V_t} \cdot 
    44         F(Q,\alpha, \psi)^2 \cdot sin(\alpha) + \text{background} 
     44        F(Q,\alpha, \psi)^2.sin(\alpha) + \text{background} 
    4545 
    46 where a numerical integration of $F(Q,\alpha, \psi)^2 \cdot sin(\alpha)$ is carried out over \alpha and \psi for: 
     46where a numerical integration of $F(Q,\alpha, \psi)^2.sin(\alpha)$ is carried out over \alpha and \psi for: 
    4747 
    4848.. math:: 
    49     :nowrap: 
    5049 
    51     \begin{align*} 
     50        \begin{align} 
    5251    F(Q,\alpha,\psi) = &\bigg[ 
    5352    (\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} \\ 
     
    5554    &+(\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} 
    5655    \bigg] 
    57     \end{align*} 
     56    \end{align} 
    5857 
    5958where 
  • sasmodels/models/core_shell_ellipsoid.py

    r30b60d2 r9f6823b  
    4444 
    4545.. math:: 
    46     :nowrap: 
    47  
    48     \begin{align*} 
     46    \begin{align} 
    4947    F(q,\alpha) = &f(q,radius\_equat\_core,radius\_equat\_core.x\_core,\alpha) \\ 
    5048    &+ f(q,radius\_equat\_core + thick\_shell,radius\_equat\_core.x\_core + thick\_shell.x\_polar\_shell,\alpha) 
    51     \end{align*} 
     49    \end{align} 
    5250 
    5351where 
  • sasmodels/models/fractal_core_shell.py

    r8f04da4 r8f04da4  
    3131$\rho_{solv}$ are the scattering length densities of the core, shell, and 
    3232solvent 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$ the 
     33of the whole particle respectively, $D_f$ is the fractal dimension, and |xi| the 
    3434correlation length. 
    3535 
  • sasmodels/models/hollow_rectangular_prism.py

    r30b60d2 r8f04da4  
    3131  :nowrap: 
    3232 
    33   \begin{align*} 
     33  \begin{align} 
    3434  A_{P\Delta}(q) & =  A B C 
    3535    \left[\frac{\sin \bigl( q \frac{C}{2} \cos\theta \bigr)} 
     
    4747    \left[ \frac{\sin \bigl[ q \bigl(\frac{B}{2}-\Delta\bigr) \sin\theta \cos\phi \bigr]} 
    4848    {q \bigl(\frac{B}{2}-\Delta\bigr) \sin\theta \cos\phi} \right] 
    49   \end{align*} 
     49  \end{align} 
    5050 
    5151where $A$, $B$ and $C$ are the external sides of the parallelepiped fulfilling 
  • sasmodels/models/multilayer_vesicle.py

    r870a2f4 r870a2f4  
    3333.. math:: 
    3434 
    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 
     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 
    3737 
    3838$\phi$ is the volume fraction of particles, $V(r)$ is the volume of a sphere 
  • sasmodels/models/parallelepiped.py

    r30b60d2 r8f04da4  
    2020   Parallelepiped with the corresponding definition of sides. 
    2121 
    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 
     24The three dimensions of the parallelepiped (strictly here a cuboid) may be given in 
     25$any$ size order. To avoid multiple fit solutions, especially 
     26with Monte-Carlo fit methods, it may be advisable to restrict their ranges. There may 
     27be a number of closely similar "best fits", so some trial and error, or fixing of some 
     28dimensions at expected values, may help. 
    2729 
    2830The 1D scattering intensity $I(q)$ is calculated as: 
  • sasmodels/models/rpa.py

    r30b60d2 r4f9e288  
    3030    These case numbers are different from those in the NIST SANS package! 
    3131 
    32 The models are based on the papers by Akcasu *et al.* and by 
    33 Hammouda assuming the polymer follows Gaussian statistics such 
     32The models are based on the papers by Akcasu et al. [#Akcasu]_ and by 
     33Hammouda [#Hammouda]_ assuming the polymer follows Gaussian statistics such 
    3434that $R_g^2 = n b^2/6$ where $b$ is the statistical segment length and $n$ is 
    3535the number of statistical segment lengths. A nice tutorial on how these are 
    3636constructed and implemented can be found in chapters 28 and 39 of Boualem 
    37 Hammouda's 'SANS Toolbox'. 
     37Hammouda's 'SANS Toolbox'[#toolbox]_. 
    3838 
    3939In brief the macroscopic cross sections are derived from the general forms 
     
    4949  are calculated with respect to component D).** So the scattering contrast 
    5050  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  
    5252  vary. 
    5353 
     
    5757      component are obtained from other methods and held fixed while The *scale* 
    5858      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 
    6162 
    6263References 
    6364---------- 
    6465 
    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 
    7170 
    7271Authorship and Verification 
  • sasmodels/models/spherical_sld.py

    r2ad5d30 r63a7fe8  
    1818Interface shapes are as follows:: 
    1919 
    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) 
    2525 
    2626Definition 
  • sasmodels/models/star_polymer.py

    r5da1ac8 r5da1ac8  
    77emanating from a common central (in the case of this model) point.  It is 
    88derived as a special case of on the Benoit model for general branched 
    9 polymers\ [#CITBenoit]_ as also used by Richter *et al.*\ [#CITRichter]_ 
     9polymers\ [#CITBenoit]_ as also used by Richter ''et. al.''\ [#CITRichter]_ 
    1010 
    1111For a star with $f$ arms the scattering intensity $I(q)$ is calculated as 
  • sasmodels/models/surface_fractal.py

    r30b60d2 r48462b0  
    99 
    1010.. math:: 
    11     :nowrap: 
    1211 
    13     \begin{align*} 
    1412    I(q) &= \text{scale} \times P(q)S(q) + \text{background} \\ 
    1513    P(q) &= F(qR)^2 \\ 
     
    1715    S(q) &= \Gamma(5-D_S)\xi^{\,5-D_S}\left[1+(q\xi)^2 \right]^{-(5-D_S)/2} 
    1816            \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 \\ 
    2018    V &= \frac{4}{3}\pi R^3 
    21     \end{align*} 
    2219 
    2320where $R$ is the radius of the building block, $D_S$ is the **surface** fractal 
  • sasmodels/product.py

    r765eb0e r8f04da4  
    6868    translate_name = dict((old.id, new.id) for old, new 
    6969                          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)) 
    7074    combined_pars = p_pars.kernel_parameters + s_list 
    7175    parameters = ParameterTable(combined_pars) 
    7276    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_pars 
    8177 
    8278    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)) 
    8581    model_info.filename = None 
    8682    model_info.title = 'Product of %s and %s'%(p_name, s_name) 
     
    8985    model_info.category = "custom" 
    9086    model_info.parameters = parameters 
    91     model_info.random = random 
    9287    #model_info.single = p_info.single and s_info.single 
    9388    model_info.structure_factor = False 
     
    10095    # TODO: delegate random to p_info, s_info 
    10196    #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 
    104100    #from .compare import get_pars, parlist 
    105101    #print("==== %s ====="%model_info.name) 
    106     #values = get_pars(model_info) 
     102    #values = get_pars(model_info, use_demo=True) 
    107103    #print(parlist(model_info, values, is2d=True)) 
    108104    return model_info 
     
    130126        self.P = P 
    131127        self.S = S 
    132         self.dtype = P.dtype 
    133128 
    134129    def make_kernel(self, q_vectors): 
  • sasmodels/sasview_model.py

    rbcdd6c9 r724257c  
    120120    else: 
    121121        model_info = modelinfo.make_model_info(kernel_module) 
    122         model = make_model_from_info(model_info) 
     122        model = _make_model_from_info(model_info) 
    123123    model.timestamp = getmtime(path) 
    124124 
     
    142142 
    143143 
    144 def make_model_from_info(model_info): 
    145     # type: (ModelInfo) -> SasviewModelType 
    146     """ 
    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.filename 
    154     ConstructedModel = type(model_info.name, (SasviewModel,), attrs) # type: SasviewModelType 
    155     return ConstructedModel 
    156  
    157  
    158144def _make_standard_model(name): 
    159145    # type: (str) -> SasviewModelType 
     
    167153    kernel_module = generate.load_kernel_module(name) 
    168154    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 
    172158def _register_old_models(): 
    173159    # type: () -> None 
     
    201187    model_info = product.make_product_info(form_factor._model_info, 
    202188                                           structure_factor._model_info) 
    203     ConstructedModel = make_model_from_info(model_info) 
     189    ConstructedModel = _make_model_from_info(model_info) 
    204190    return ConstructedModel() 
    205191 
     192def _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 
    206204 
    207205def _generate_model_attributes(model_info): 
     
    605603        if hasattr(self._model_info, "composition") \ 
    606604           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])() 
    609607        return p_model, s_model 
    610608 
Note: See TracChangeset for help on using the changeset viewer.