Changes in / [b3f4831:5778279] in sasmodels


Ignore:
Files:
1 deleted
18 edited

Legend:

Unmodified
Added
Removed
  • doc/guide/magnetism/magnetism.rst

    rdf87acf rbefe905  
    8989 
    9090===========   ================================================================ 
    91  sld_M0       $D_M M_0$ 
    92  sld_mtheta   $\theta_M$ 
    93  sld_mphi     $\phi_M$ 
    94  up_frac_i    $u_i$ = (spin up)/(spin up + spin down) *before* the sample 
    95  up_frac_f    $u_f$ = (spin up)/(spin up + spin down) *after* the sample 
    96  up_angle     $\theta_\mathrm{up}$ 
     91 M0:sld       $D_M M_0$ 
     92 mtheta:sld   $\theta_M$ 
     93 mphi:sld     $\phi_M$ 
     94 up:angle     $\theta_\mathrm{up}$ 
     95 up:frac_i    $u_i$ = (spin up)/(spin up + spin down) *before* the sample 
     96 up:frac_f    $u_f$ = (spin up)/(spin up + spin down) *after* the sample 
    9797===========   ================================================================ 
    9898 
    9999.. note:: 
    100     The values of the 'up_frac_i' and 'up_frac_f' must be in the range 0 to 1. 
     100    The values of the 'up:frac_i' and 'up:frac_f' must be in the range 0 to 1. 
    101101 
    102102*Document History* 
  • doc/guide/plugin.rst

    r57c609b rf796469  
    423423calculations, but instead rely on numerical integration to compute the 
    424424appropriately smeared pattern. 
    425  
    426 Each .py file also contains a function:: 
    427  
    428         def random(): 
    429         ... 
    430  
    431 This function provides a model-specific random parameter set which shows model 
    432 features in the USANS to SANS range.  For example, core-shell sphere sets the 
    433 outer radius of the sphere logarithmically in `[20, 20,000]`, which sets the Q 
    434 value for the transition from flat to falling.  It then uses a beta distribution 
    435 to set the percentage of the shape which is shell, giving a preference for very 
    436 thin or very thick shells (but never 0% or 100%).  Using `-sets=10` in sascomp 
    437 should show a reasonable variety of curves over the default sascomp q range. 
    438 The parameter set is returned as a dictionary of `{parameter: value, ...}`. 
    439 Any model parameters not included in the dictionary will default according to 
    440 the code in the `_randomize_one()` function from sasmodels/compare.py. 
    441425 
    442426Python Models 
     
    701685    erf, erfc, tgamma, lgamma:  **do not use** 
    702686        Special functions that should be part of the standard, but are missing 
    703         or inaccurate on some platforms. Use sas_erf, sas_erfc, sas_gamma 
    704         and sas_lgamma instead (see below). 
     687        or inaccurate on some platforms. Use sas_erf, sas_erfc and sas_gamma 
     688        instead (see below). Note: lgamma(x) has not yet been tested. 
    705689 
    706690Some non-standard constants and functions are also provided: 
     
    769753        Gamma function sas_gamma\ $(x) = \Gamma(x)$. 
    770754 
    771         The standard math function, tgamma(x), is unstable for $x < 1$ 
     755        The standard math function, tgamma(x) is unstable for $x < 1$ 
    772756        on some platforms. 
    773757 
    774758        :code:`source = ["lib/sas_gamma.c", ...]` 
    775759        (`sas_gamma.c <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_gamma.c>`_) 
    776  
    777     sas_gammaln(x): 
    778         log gamma function sas_gammaln\ $(x) = \log \Gamma(|x|)$. 
    779  
    780         The standard math function, lgamma(x), is incorrect for single 
    781         precision on some platforms. 
    782  
    783         :code:`source = ["lib/sas_gammainc.c", ...]` 
    784         (`sas_gammainc.c <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_gammainc.c>`_) 
    785  
    786     sas_gammainc(a, x), sas_gammaincc(a, x): 
    787         Incomplete gamma function 
    788         sas_gammainc\ $(a, x) = \int_0^x t^{a-1}e^{-t}\,dt / \Gamma(a)$ 
    789         and complementary incomplete gamma function 
    790         sas_gammaincc\ $(a, x) = \int_x^\infty t^{a-1}e^{-t}\,dt / \Gamma(a)$ 
    791  
    792         :code:`source = ["lib/sas_gammainc.c", ...]` 
    793         (`sas_gammainc.c <https://github.com/SasView/sasmodels/tree/master/sasmodels/models/lib/sas_gammainc.c>`_) 
    794760 
    795761    sas_erf(x), sas_erfc(x): 
     
    829795        If $n$ = 0 or 1, it uses sas_J0($x$) or sas_J1($x$), respectively. 
    830796 
    831         Warning: JN(n,x) can be very inaccurate (0.1%) for x not in [0.1, 100]. 
    832  
    833797        The standard math function jn(n, x) is not available on all platforms. 
    834798 
     
    839803        Sine integral Si\ $(x) = \int_0^x \tfrac{\sin t}{t}\,dt$. 
    840804 
    841         Warning: Si(x) can be very inaccurate (0.1%) for x in [0.1, 100]. 
    842  
    843805        This function uses Taylor series for small and large arguments: 
    844806 
    845         For large arguments use the following Taylor series, 
     807        For large arguments, 
    846808 
    847809        .. math:: 
     
    851813             - \frac{\sin(x)}{x}\left(\frac{1}{x} - \frac{3!}{x^3} + \frac{5!}{x^5} - \frac{7!}{x^7}\right) 
    852814 
    853         For small arguments , 
     815        For small arguments, 
    854816 
    855817        .. math:: 
  • explore/precision.py

    rfba9ca0 r2a7e20e  
    9595            neg:    [-100,100] 
    9696 
    97         For arbitrary range use "start:stop:steps:scale" where scale is 
    98         one of log, lin, or linear. 
    99  
    10097        *diff* is "relative", "absolute" or "none" 
    10198 
     
    105102        linear = not xrange.startswith("log") 
    106103        if xrange == "zoom": 
    107             start, stop, steps = 1000, 1010, 2000 
     104            lin_min, lin_max, lin_steps = 1000, 1010, 2000 
    108105        elif xrange == "neg": 
    109             start, stop, steps = -100.1, 100.1, 2000 
     106            lin_min, lin_max, lin_steps = -100.1, 100.1, 2000 
    110107        elif xrange == "linear": 
    111             start, stop, steps = 1, 1000, 2000 
    112             start, stop, steps = 0.001, 2, 2000 
     108            lin_min, lin_max, lin_steps = 1, 1000, 2000 
     109            lin_min, lin_max, lin_steps = 0.001, 2, 2000 
    113110        elif xrange == "log": 
    114             start, stop, steps = -3, 5, 400 
     111            log_min, log_max, log_steps = -3, 5, 400 
    115112        elif xrange == "logq": 
    116             start, stop, steps = -4, 1, 400 
    117         elif ':' in xrange: 
    118             parts = xrange.split(':') 
    119             linear = parts[3] != "log" if len(parts) == 4 else True 
    120             steps = int(parts[2]) if len(parts) > 2 else 400 
    121             start = float(parts[0]) 
    122             stop = float(parts[1]) 
    123  
     113            log_min, log_max, log_steps = -4, 1, 400 
    124114        else: 
    125115            raise ValueError("unknown range "+xrange) 
     
    131121            # value to x in the given precision. 
    132122            if linear: 
    133                 start = max(start, self.limits[0]) 
    134                 stop = min(stop, self.limits[1]) 
    135                 qrf = np.linspace(start, stop, steps, dtype='single') 
    136                 #qrf = np.linspace(start, stop, steps, dtype='double') 
     123                lin_min = max(lin_min, self.limits[0]) 
     124                lin_max = min(lin_max, self.limits[1]) 
     125                qrf = np.linspace(lin_min, lin_max, lin_steps, dtype='single') 
     126                #qrf = np.linspace(lin_min, lin_max, lin_steps, dtype='double') 
    137127                qr = [mp.mpf(float(v)) for v in qrf] 
    138                 #qr = mp.linspace(start, stop, steps) 
     128                #qr = mp.linspace(lin_min, lin_max, lin_steps) 
    139129            else: 
    140                 start = np.log10(max(10**start, self.limits[0])) 
    141                 stop = np.log10(min(10**stop, self.limits[1])) 
    142                 qrf = np.logspace(start, stop, steps, dtype='single') 
    143                 #qrf = np.logspace(start, stop, steps, dtype='double') 
     130                log_min = np.log10(max(10**log_min, self.limits[0])) 
     131                log_max = np.log10(min(10**log_max, self.limits[1])) 
     132                qrf = np.logspace(log_min, log_max, log_steps, dtype='single') 
     133                #qrf = np.logspace(log_min, log_max, log_steps, dtype='double') 
    144134                qr = [mp.mpf(float(v)) for v in qrf] 
    145                 #qr = [10**v for v in mp.linspace(start, stop, steps)] 
     135                #qr = [10**v for v in mp.linspace(log_min, log_max, log_steps)] 
    146136 
    147137        target = self.call_mpmath(qr, bits=500) 
     
    186176    """ 
    187177    if diff == "relative": 
    188         err = np.array([(abs((t-a)/t) if t != 0 else a) for t, a in zip(target, actual)], 'd') 
     178        err = np.array([abs((t-a)/t) for t, a in zip(target, actual)], 'd') 
    189179        #err = np.clip(err, 0, 1) 
    190180        pylab.loglog(x, err, '-', label=label) 
     
    207197    return model_info 
    208198 
    209 # Hack to allow second parameter A in two parameter functions 
    210 A = 1 
    211 def parse_extra_pars(): 
    212     global A 
    213  
    214     A_str = str(A) 
    215     pop = [] 
    216     for k, v in enumerate(sys.argv[1:]): 
    217         if v.startswith("A="): 
    218             A_str = v[2:] 
    219             pop.append(k+1) 
    220     if pop: 
    221         sys.argv = [v for k, v in enumerate(sys.argv) if k not in pop] 
    222         A = float(A_str) 
    223  
    224 parse_extra_pars() 
    225  
    226199 
    227200# =============== FUNCTION DEFINITIONS ================ 
     
    324297    ocl_function=make_ocl("return sas_gamma(q);", "sas_gamma", ["lib/sas_gamma.c"]), 
    325298    limits=(-3.1, 10), 
    326 ) 
    327 add_function( 
    328     name="gammaln(x)", 
    329     mp_function=mp.loggamma, 
    330     np_function=scipy.special.gammaln, 
    331     ocl_function=make_ocl("return sas_gammaln(q);", "sas_gammaln", ["lib/sas_gammainc.c"]), 
    332     #ocl_function=make_ocl("return lgamma(q);", "sas_gammaln"), 
    333 ) 
    334 add_function( 
    335     name="gammainc(x)", 
    336     mp_function=lambda x, a=A: mp.gammainc(a, a=0, b=x)/mp.gamma(a), 
    337     np_function=lambda x, a=A: scipy.special.gammainc(a, x), 
    338     ocl_function=make_ocl("return sas_gammainc(%.15g,q);"%A, "sas_gammainc", ["lib/sas_gammainc.c"]), 
    339 ) 
    340 add_function( 
    341     name="gammaincc(x)", 
    342     mp_function=lambda x, a=A: mp.gammainc(a, a=x, b=mp.inf)/mp.gamma(a), 
    343     np_function=lambda x, a=A: scipy.special.gammaincc(a, x), 
    344     ocl_function=make_ocl("return sas_gammaincc(%.15g,q);"%A, "sas_gammaincc", ["lib/sas_gammainc.c"]), 
    345299) 
    346300add_function( 
     
    509463lanczos_gamma = """\ 
    510464    const double coeff[] = { 
    511             76.18009172947146, -86.50532032941677, 
    512             24.01409824083091, -1.231739572450155, 
     465            76.18009172947146,     -86.50532032941677, 
     466            24.01409824083091,     -1.231739572450155, 
    513467            0.1208650973866179e-2,-0.5395239384953e-5 
    514468            }; 
     
    521475""" 
    522476add_function( 
    523     name="loggamma(x)", 
     477    name="log gamma(x)", 
    524478    mp_function=mp.loggamma, 
    525479    np_function=scipy.special.gammaln, 
     
    645599 
    646600ALL_FUNCTIONS = set(FUNCTIONS.keys()) 
    647 ALL_FUNCTIONS.discard("loggamma")  # use cephes-based gammaln instead 
     601ALL_FUNCTIONS.discard("loggamma")  # OCL version not ready yet 
    648602ALL_FUNCTIONS.discard("3j1/x:taylor") 
    649603ALL_FUNCTIONS.discard("3j1/x:trig") 
     
    661615    -r indicates that the relative error should be plotted (default), 
    662616    -x<range> indicates the steps in x, where <range> is one of the following 
    663         log indicates log stepping in [10^-3, 10^5] (default) 
    664         logq indicates log stepping in [10^-4, 10^1] 
    665         linear indicates linear stepping in [1, 1000] 
    666         zoom indicates linear stepping in [1000, 1010] 
    667         neg indicates linear stepping in [-100.1, 100.1] 
    668         start:stop:n[:stepping] indicates an n-step plot in [start, stop] 
    669             or [10^start, 10^stop] if stepping is "log" (default n=400) 
    670 Some functions (notably gammainc/gammaincc) have an additional parameter A 
    671 which can be set from the command line as A=value.  Default is A=1. 
    672  
    673 Name is one of: 
     617      log indicates log stepping in [10^-3, 10^5] (default) 
     618      logq indicates log stepping in [10^-4, 10^1] 
     619      linear indicates linear stepping in [1, 1000] 
     620      zoom indicates linear stepping in [1000, 1010] 
     621      neg indicates linear stepping in [-100.1, 100.1] 
     622and name is "all" or one of: 
    674623    """+names) 
    675624    sys.exit(1) 
  • sasmodels/__init__.py

    ra1ec908 re65c3ba  
    1414defining new models. 
    1515""" 
    16 __version__ = "0.98" 
     16__version__ = "0.97" 
    1717 
    1818def data_files(): 
  • sasmodels/compare.py

    r610ef23 rbd7630d  
    368368 
    369369    # Limit magnetic SLDs to a smaller range, from zero to iron=5/A^2 
    370     if par.name.endswith('_M0'): 
     370    if par.name.startswith('M0:'): 
    371371        return np.random.uniform(0, 5) 
    372372 
     
    538538    magnetic_pars = [] 
    539539    for p in parameters.user_parameters(pars, is2d): 
    540         if any(p.id.endswith(x) for x in ('_M0', '_mtheta', '_mphi')): 
     540        if any(p.id.startswith(x) for x in ('M0:', 'mtheta:', 'mphi:')): 
    541541            continue 
    542542        if p.id.startswith('up:'): 
     
    550550            pdtype=pars.get(p.id+"_pd_type", 'gaussian'), 
    551551            relative_pd=p.relative_pd, 
    552             M0=pars.get(p.id+'_M0', 0.), 
    553             mphi=pars.get(p.id+'_mphi', 0.), 
    554             mtheta=pars.get(p.id+'_mtheta', 0.), 
     552            M0=pars.get('M0:'+p.id, 0.), 
     553            mphi=pars.get('mphi:'+p.id, 0.), 
     554            mtheta=pars.get('mtheta:'+p.id, 0.), 
    555555        ) 
    556556        lines.append(_format_par(p.name, **fields)) 
     
    618618    if suppress: 
    619619        for p in pars: 
    620             if p.endswith("_M0"): 
     620            if p.startswith("M0:"): 
    621621                pars[p] = 0 
    622622    else: 
     
    624624        first_mag = None 
    625625        for p in pars: 
    626             if p.endswith("_M0"): 
     626            if p.startswith("M0:"): 
    627627                any_mag |= (pars[p] != 0) 
    628628                if first_mag is None: 
  • sasmodels/convert.py

    r610ef23 r78f8308  
    167167    if version < (4, 2, 0): 
    168168        oldpars = _hand_convert_4_1_to_4_2(name, oldpars) 
    169         oldpars = _rename_magnetic_pars(oldpars) 
    170169    return oldpars 
    171170 
     
    175174        oldpars['lattice_distortion'] = oldpars.pop('d_factor') 
    176175    return oldpars 
    177  
    178 def _rename_magnetic_pars(pars): 
    179     """ 
    180     Change from M0:par to par_M0, etc. 
    181     """ 
    182     keys = list(pars.items()) 
    183     for k in keys: 
    184         if k.startswith('M0:'): 
    185             pars[k[3:]+'_M0'] = pars.pop(k) 
    186         elif k.startswith('mtheta:'): 
    187             pars[k[7:]+'_mtheta'] = pars.pop(k) 
    188         elif k.startswith('mphi:'): 
    189             pars[k[5:]+'_mphi'] = pars.pop(k) 
    190         elif k.startswith('up:'): 
    191             pars['up_'+k[3:]] = pars.pop(k) 
    192     return pars 
    193176 
    194177def _hand_convert_3_1_2_to_4_1(name, oldpars): 
  • sasmodels/custom/__init__.py

    rd321747 r0f48f1e  
    1212import sys 
    1313import os 
    14 from os.path import basename, splitext, join as joinpath, exists, dirname 
     14from os.path import basename, splitext 
    1515 
    1616try: 
     
    1818    from importlib.util import spec_from_file_location, module_from_spec  # type: ignore 
    1919    def load_module_from_path(fullname, path): 
    20         # type: (str, str) -> "module" 
    2120        """load module from *path* as *fullname*""" 
    2221        spec = spec_from_file_location(fullname, os.path.expanduser(path)) 
     
    2827    import imp 
    2928    def load_module_from_path(fullname, path): 
    30         # type: (str, str) -> "module" 
    3129        """load module from *path* as *fullname*""" 
    3230        # Clear out old definitions, if any 
     
    3937        return module 
    4038 
    41 _MODULE_CACHE = {} # type: Dict[str, Tuple("module", int)] 
    42 _MODULE_DEPENDS = {} # type: Dict[str, List[str]] 
    43 _MODULE_DEPENDS_STACK = [] # type: List[str] 
    4439def load_custom_kernel_module(path): 
    45     # type: str -> "module" 
    4640    """load SAS kernel from *path* as *sasmodels.custom.modelname*""" 
    4741    # Pull off the last .ext if it exists; there may be others 
    4842    name = basename(splitext(path)[0]) 
    49     path = os.path.expanduser(path) 
    50  
    51     # Reload module if necessary. 
    52     if need_reload(path): 
    53         # Assume the module file is the only dependency 
    54         _MODULE_DEPENDS[path] = set([path]) 
    55  
    56         # Load the module while pushing it onto the dependency stack.  If 
    57         # this triggers any submodules, then they will add their dependencies 
    58         # to this module as the "working_on" parent.  Pop the stack when the 
    59         # module is loaded. 
    60         _MODULE_DEPENDS_STACK.append(path) 
    61         module = load_module_from_path('sasmodels.custom.'+name, path) 
    62         _MODULE_DEPENDS_STACK.pop() 
    63  
    64         # Include external C code in the dependencies.  We are looking 
    65         # for module.source and assuming that it is a list of C source files 
    66         # relative to the module itself.  Any files that do not exist, 
    67         # such as those in the standard libraries, will be ignored. 
    68         # TODO: look in builtin module path for standard c sources 
    69         # TODO: share code with generate.model_sources 
    70         c_sources = getattr(module, 'source', None) 
    71         if isinstance(c_sources, (list, tuple)): 
    72             _MODULE_DEPENDS[path].update(_find_sources(path, c_sources)) 
    73  
    74         # Cache the module, and tag it with the newest timestamp 
    75         timestamp = max(os.path.getmtime(f) for f in _MODULE_DEPENDS[path]) 
    76         _MODULE_CACHE[path] = module, timestamp 
    77  
    78         #print("loading", os.path.basename(path), _MODULE_CACHE[path][1], 
    79         #    [os.path.basename(p) for p in _MODULE_DEPENDS[path]]) 
    80  
    81     # Add path and all its dependence to the parent module, if there is one. 
    82     if _MODULE_DEPENDS_STACK: 
    83         working_on = _MODULE_DEPENDS_STACK[-1] 
    84         _MODULE_DEPENDS[working_on].update(_MODULE_DEPENDS[path]) 
    85  
    86     return _MODULE_CACHE[path][0] 
    87  
    88 def need_reload(path): 
    89     # type: str -> bool 
    90     """ 
    91     Return True if any path dependencies have a timestamp newer than the time 
    92     when the path was most recently loaded. 
    93     """ 
    94     # TODO: fails if a dependency has a modification time in the future 
    95     # If the newest dependency has a time stamp in the future, then this 
    96     # will be recorded as the cached time.  When a second dependency 
    97     # is updated to the current time stamp, it will still be considered 
    98     # older than the current build and the reload will not be triggered. 
    99     # Could instead treat all future times as 0 here and in the code above 
    100     # which records the newest timestamp.  This will force a reload when 
    101     # the future time is reached, but other than that should perform 
    102     # correctly.  Probably not worth the extra code... 
    103     _, cache_time = _MODULE_CACHE.get(path, (None, -1)) 
    104     depends = _MODULE_DEPENDS.get(path, [path]) 
    105     #print("reload", any(cache_time < os.path.getmtime(p) for p in depends)) 
    106     #for f in depends: print(">>>  ", f, os.path.getmtime(f)) 
    107     return any(cache_time < os.path.getmtime(p) for p in depends) 
    108  
    109 def _find_sources(path, source_list): 
    110     # type: (str, List[str]) -> List[str] 
    111     """ 
    112     Return a list of the sources relative to base file; ignore any that 
    113     are not found. 
    114     """ 
    115     root = dirname(path) 
    116     found = [] 
    117     for source_name in source_list: 
    118         source_path = joinpath(root, source_name) 
    119         if exists(source_path): 
    120             found.append(source_path) 
    121     return found 
     43    # Placing the model in the 'sasmodels.custom' name space. 
     44    kernel_module = load_module_from_path('sasmodels.custom.'+name, 
     45                                          os.path.expanduser(path)) 
     46    return kernel_module 
  • sasmodels/kernelpy.py

    r91bd550 r108e70e  
    3737        self.info = model_info 
    3838        self.dtype = np.dtype('d') 
    39         logger.info("make python model " + self.info.name) 
     39        logger.info("load python model " + self.info.name) 
    4040 
    4141    def make_kernel(self, q_vectors): 
  • sasmodels/model_test.py

    r12eec1e r012cd34  
    4747import sys 
    4848import unittest 
    49 import traceback 
    5049 
    5150try: 
     
    7574# pylint: enable=unused-import 
    7675 
     76 
    7777def make_suite(loaders, models): 
    7878    # type: (List[str], List[str]) -> unittest.TestSuite 
     
    8686    *models* is the list of models to test, or *["all"]* to test all models. 
    8787    """ 
     88    ModelTestCase = _hide_model_case_from_nose() 
    8889    suite = unittest.TestSuite() 
    8990 
     
    9495        skip = [] 
    9596    for model_name in models: 
    96         if model_name not in skip: 
    97             model_info = load_model_info(model_name) 
    98             _add_model_to_suite(loaders, suite, model_info) 
     97        if model_name in skip: 
     98            continue 
     99        model_info = load_model_info(model_name) 
     100 
     101        #print('------') 
     102        #print('found tests in', model_name) 
     103        #print('------') 
     104 
     105        # if ispy then use the dll loader to call pykernel 
     106        # don't try to call cl kernel since it will not be 
     107        # available in some environmentes. 
     108        is_py = callable(model_info.Iq) 
     109 
     110        # Some OpenCL drivers seem to be flaky, and are not producing the 
     111        # expected result.  Since we don't have known test values yet for 
     112        # all of our models, we are instead going to compare the results 
     113        # for the 'smoke test' (that is, evaluation at q=0.1 for the default 
     114        # parameters just to see that the model runs to completion) between 
     115        # the OpenCL and the DLL.  To do this, we define a 'stash' which is 
     116        # shared between OpenCL and DLL tests.  This is just a list.  If the 
     117        # list is empty (which it will be when DLL runs, if the DLL runs 
     118        # first), then the results are appended to the list.  If the list 
     119        # is not empty (which it will be when OpenCL runs second), the results 
     120        # are compared to the results stored in the first element of the list. 
     121        # This is a horrible stateful hack which only makes sense because the 
     122        # test suite is thrown away after being run once. 
     123        stash = [] 
     124 
     125        if is_py:  # kernel implemented in python 
     126            test_name = "%s-python"%model_name 
     127            test_method_name = "test_%s_python" % model_info.id 
     128            test = ModelTestCase(test_name, model_info, 
     129                                 test_method_name, 
     130                                 platform="dll",  # so that 
     131                                 dtype="double", 
     132                                 stash=stash) 
     133            suite.addTest(test) 
     134        else:   # kernel implemented in C 
     135 
     136            # test using dll if desired 
     137            if 'dll' in loaders or not use_opencl(): 
     138                test_name = "%s-dll"%model_name 
     139                test_method_name = "test_%s_dll" % model_info.id 
     140                test = ModelTestCase(test_name, model_info, 
     141                                     test_method_name, 
     142                                     platform="dll", 
     143                                     dtype="double", 
     144                                     stash=stash) 
     145                suite.addTest(test) 
     146 
     147            # test using opencl if desired and available 
     148            if 'opencl' in loaders and use_opencl(): 
     149                test_name = "%s-opencl"%model_name 
     150                test_method_name = "test_%s_opencl" % model_info.id 
     151                # Using dtype=None so that the models that are only 
     152                # correct for double precision are not tested using 
     153                # single precision.  The choice is determined by the 
     154                # presence of *single=False* in the model file. 
     155                test = ModelTestCase(test_name, model_info, 
     156                                     test_method_name, 
     157                                     platform="ocl", dtype=None, 
     158                                     stash=stash) 
     159                #print("defining", test_name) 
     160                suite.addTest(test) 
    99161 
    100162    return suite 
    101  
    102 def _add_model_to_suite(loaders, suite, model_info): 
    103     ModelTestCase = _hide_model_case_from_nose() 
    104  
    105     #print('------') 
    106     #print('found tests in', model_name) 
    107     #print('------') 
    108  
    109     # if ispy then use the dll loader to call pykernel 
    110     # don't try to call cl kernel since it will not be 
    111     # available in some environmentes. 
    112     is_py = callable(model_info.Iq) 
    113  
    114     # Some OpenCL drivers seem to be flaky, and are not producing the 
    115     # expected result.  Since we don't have known test values yet for 
    116     # all of our models, we are instead going to compare the results 
    117     # for the 'smoke test' (that is, evaluation at q=0.1 for the default 
    118     # parameters just to see that the model runs to completion) between 
    119     # the OpenCL and the DLL.  To do this, we define a 'stash' which is 
    120     # shared between OpenCL and DLL tests.  This is just a list.  If the 
    121     # list is empty (which it will be when DLL runs, if the DLL runs 
    122     # first), then the results are appended to the list.  If the list 
    123     # is not empty (which it will be when OpenCL runs second), the results 
    124     # are compared to the results stored in the first element of the list. 
    125     # This is a horrible stateful hack which only makes sense because the 
    126     # test suite is thrown away after being run once. 
    127     stash = [] 
    128  
    129     if is_py:  # kernel implemented in python 
    130         test_name = "%s-python"%model_info.name 
    131         test_method_name = "test_%s_python" % model_info.id 
    132         test = ModelTestCase(test_name, model_info, 
    133                                 test_method_name, 
    134                                 platform="dll",  # so that 
    135                                 dtype="double", 
    136                                 stash=stash) 
    137         suite.addTest(test) 
    138     else:   # kernel implemented in C 
    139  
    140         # test using dll if desired 
    141         if 'dll' in loaders or not use_opencl(): 
    142             test_name = "%s-dll"%model_info.name 
    143             test_method_name = "test_%s_dll" % model_info.id 
    144             test = ModelTestCase(test_name, model_info, 
    145                                     test_method_name, 
    146                                     platform="dll", 
    147                                     dtype="double", 
    148                                     stash=stash) 
    149             suite.addTest(test) 
    150  
    151         # test using opencl if desired and available 
    152         if 'opencl' in loaders and use_opencl(): 
    153             test_name = "%s-opencl"%model_info.name 
    154             test_method_name = "test_%s_opencl" % model_info.id 
    155             # Using dtype=None so that the models that are only 
    156             # correct for double precision are not tested using 
    157             # single precision.  The choice is determined by the 
    158             # presence of *single=False* in the model file. 
    159             test = ModelTestCase(test_name, model_info, 
    160                                     test_method_name, 
    161                                     platform="ocl", dtype=None, 
    162                                     stash=stash) 
    163             #print("defining", test_name) 
    164             suite.addTest(test) 
    165  
    166163 
    167164def _hide_model_case_from_nose(): 
     
    351348    return abs(target-actual)/shift < 1.5*10**-digits 
    352349 
    353 # CRUFT: old interface; should be deprecated and removed 
    354 def run_one(model_name): 
    355     # msg = "use check_model(model_info) rather than run_one(model_name)" 
    356     # warnings.warn(msg, category=DeprecationWarning, stacklevel=2) 
    357     try: 
    358         model_info = load_model_info(model_name) 
    359     except Exception: 
    360         output = traceback.format_exc() 
    361         return output 
    362  
    363     success, output = check_model(model_info) 
    364     return output 
    365  
    366 def check_model(model_info): 
    367     # type: (ModelInfo) -> str 
    368     """ 
    369     Run the tests for a single model, capturing the output. 
    370  
    371     Returns success status and the output string. 
     350def run_one(model): 
     351    # type: (str) -> str 
     352    """ 
     353    Run the tests for a single model, printing the results to stdout. 
     354 
     355    *model* can by a python file, which is handy for checking user defined 
     356    plugin models. 
    372357    """ 
    373358    # Note that running main() directly did not work from within the 
     
    384369    # Build a test suite containing just the model 
    385370    loaders = ['opencl'] if use_opencl() else ['dll'] 
    386     suite = unittest.TestSuite() 
    387     _add_model_to_suite(loaders, suite, model_info) 
     371    models = [model] 
     372    try: 
     373        suite = make_suite(loaders, models) 
     374    except Exception: 
     375        import traceback 
     376        stream.writeln(traceback.format_exc()) 
     377        return 
    388378 
    389379    # Warn if there are no user defined tests. 
     
    400390    for test in suite: 
    401391        if not test.info.tests: 
    402             stream.writeln("Note: %s has no user defined tests."%model_info.name) 
     392            stream.writeln("Note: %s has no user defined tests."%model) 
    403393        break 
    404394    else: 
     
    416406    output = stream.getvalue() 
    417407    stream.close() 
    418     return result.wasSuccessful(), output 
     408    return output 
    419409 
    420410 
  • sasmodels/modelinfo.py

    rbd547d0 r7b9e4dd  
    466466        self.is_asymmetric = any(p.name == 'psi' for p in self.kernel_parameters) 
    467467        self.magnetism_index = [k for k, p in enumerate(self.call_parameters) 
    468                                 if p.id.endswith('_M0')] 
     468                                if p.id.startswith('M0:')] 
    469469 
    470470        self.pd_1d = set(p.name for p in self.call_parameters 
     
    586586        if self.nmagnetic > 0: 
    587587            full_list.extend([ 
    588                 Parameter('up_frac_i', '', 0., [0., 1.], 
     588                Parameter('up:frac_i', '', 0., [0., 1.], 
    589589                          'magnetic', 'fraction of spin up incident'), 
    590                 Parameter('up_frac_f', '', 0., [0., 1.], 
     590                Parameter('up:frac_f', '', 0., [0., 1.], 
    591591                          'magnetic', 'fraction of spin up final'), 
    592                 Parameter('up_angle', 'degrees', 0., [0., 360.], 
     592                Parameter('up:angle', 'degrees', 0., [0., 360.], 
    593593                          'magnetic', 'spin up angle'), 
    594594            ]) 
     
    596596            for p in slds: 
    597597                full_list.extend([ 
    598                     Parameter(p.id+'_M0', '1e-6/Ang^2', 0., [-np.inf, np.inf], 
     598                    Parameter('M0:'+p.id, '1e-6/Ang^2', 0., [-np.inf, np.inf], 
    599599                              'magnetic', 'magnetic amplitude for '+p.description), 
    600                     Parameter(p.id+'_mtheta', 'degrees', 0., [-90., 90.], 
     600                    Parameter('mtheta:'+p.id, 'degrees', 0., [-90., 90.], 
    601601                              'magnetic', 'magnetic latitude for '+p.description), 
    602                     Parameter(p.id+'_mphi', 'degrees', 0., [-180., 180.], 
     602                    Parameter('mphi:'+p.id, 'degrees', 0., [-180., 180.], 
    603603                              'magnetic', 'magnetic longitude for '+p.description), 
    604604                ]) 
     
    640640 
    641641        Parameters marked as sld will automatically have a set of associated 
    642         magnetic parameters (p_M0, p_mtheta, p_mphi), as well as polarization 
    643         information (up_theta, up_frac_i, up_frac_f). 
     642        magnetic parameters (m0:p, mtheta:p, mphi:p), as well as polarization 
     643        information (up:theta, up:frac_i, up:frac_f). 
    644644        """ 
    645645        # control parameters go first 
     
    668668            result.append(expanded_pars[name]) 
    669669            if is2d: 
    670                 for tag in '_M0', '_mtheta', '_mphi': 
    671                     if name+tag in expanded_pars: 
    672                         result.append(expanded_pars[name+tag]) 
     670                for tag in 'M0:', 'mtheta:', 'mphi:': 
     671                    if tag+name in expanded_pars: 
     672                        result.append(expanded_pars[tag+name]) 
    673673 
    674674        # Gather the user parameters in order 
     
    703703                append_group(p.id) 
    704704 
    705         if is2d and 'up_angle' in expanded_pars: 
     705        if is2d and 'up:angle' in expanded_pars: 
    706706            result.extend([ 
    707                 expanded_pars['up_frac_i'], 
    708                 expanded_pars['up_frac_f'], 
    709                 expanded_pars['up_angle'], 
     707                expanded_pars['up:frac_i'], 
     708                expanded_pars['up:frac_f'], 
     709                expanded_pars['up:angle'], 
    710710            ]) 
    711711 
     
    793793    info.structure_factor = getattr(kernel_module, 'structure_factor', False) 
    794794    info.profile_axes = getattr(kernel_module, 'profile_axes', ['x', 'y']) 
    795     # Note: custom.load_custom_kernel_module assumes the C sources are defined 
    796     # by this attribute. 
    797795    info.source = getattr(kernel_module, 'source', []) 
    798796    info.c_code = getattr(kernel_module, 'c_code', None) 
     
    10161014                         for k in range(control+1, p.length+1) 
    10171015                         if p.length > 1) 
    1018             for p in self.parameters.kernel_parameters: 
    1019                 if p.length > 1 and p.type == "sld": 
    1020                     for k in range(control+1, p.length+1): 
    1021                         base = p.id+str(k) 
    1022                         hidden.update((base+"_M0", base+"_mtheta", base+"_mphi")) 
    10231016        return hidden 
  • sasmodels/models/bcc_paracrystal.py

    rda7b26b re7e9231  
    11r""" 
    2 .. warning:: This model and this model description are under review following  
    3              concerns raised by SasView users. If you need to use this model,  
    4              please email help@sasview.org for the latest situation. *The  
    5              SasView Developers. September 2018.* 
    6  
    72Definition 
    83---------- 
     
    1813 
    1914    I(q) = \frac{\text{scale}}{V_p} V_\text{lattice} P(q) Z(q) 
     15 
    2016 
    2117where *scale* is the volume fraction of spheres, $V_p$ is the volume of the 
     
    10197 
    10298Authorship and Verification 
    103 --------------------------- 
     99---------------------------- 
    104100 
    105101* **Author:** NIST IGOR/DANSE **Date:** pre 2010 
  • sasmodels/models/be_polyelectrolyte.py

    rca77fc1 ref07e95  
    11r""" 
    2 .. note:: Please read the Validation section below. 
    3  
    42Definition 
    53---------- 
     
    1311 
    1412    I(q) = K\frac{q^2+k^2}{4\pi L_b\alpha ^2} 
    15     \frac{1}{1+r_{0}^4(q^2+k^2)(q^2-12hC_a/b^2)} + background 
     13    \frac{1}{1+r_{0}^2(q^2+k^2)(q^2-12hC_a/b^2)} + background 
    1614 
    1715    k^2 = 4\pi L_b(2C_s + \alpha C_a) 
    1816 
    19     r_{0}^2 = \frac{b}{\alpha \sqrt{C_a 48\pi L_b}} 
     17    r_{0}^2 = \frac{1}{\alpha \sqrt{C_a} \left( b/\sqrt{48\pi L_b}\right)} 
    2018 
    2119where 
    2220 
    2321$K$ is the contrast factor for the polymer which is defined differently than in 
    24 other models and is given in barns where 1 $barn = 10^{-24}$ $cm^2$.  $K$ is 
     22other models and is given in barns where $1 barn = 10^{-24} cm^2$.  $K$ is 
    2523defined as: 
    2624 
     
    3129    a = b_p - (v_p/v_s) b_s 
    3230 
    33 where: 
    34  
    35 - $b_p$ and $b_s$ are **sum of the scattering lengths of the atoms** 
    36   constituting the polymer monomer and the solvent molecules, respectively. 
    37  
    38 - $v_p$ and $v_s$ are the partial molar volume of the polymer and the  
    39   solvent, respectively. 
    40  
    41 - $L_b$ is the Bjerrum length (|Ang|) - **Note:** This parameter needs to be 
    42   kept constant for a given solvent and temperature! 
    43  
    44 - $h$ is the virial parameter (|Ang^3|) - **Note:** See [#Borue]_ for the 
    45   correct interpretation of this parameter.  It incorporates second and third 
    46   virial coefficients and can be *negative*. 
    47  
    48 - $b$ is the monomer length (|Ang|). 
    49  
    50 - $C_s$ is the concentration of monovalent salt(1/|Ang^3| - internally converted from mol/L). 
    51  
    52 - $\alpha$ is the degree of ionization (the ratio of charged monomers to the total  
    53   number of monomers) 
    54  
    55 - $C_a$ is the polymer molar concentration (1/|Ang^3| - internally converted from mol/L) 
    56  
    57 - $background$ is the incoherent background. 
     31where $b_p$ and $b_s$ are sum of the scattering lengths of the atoms 
     32constituting the monomer of the polymer and the sum of the scattering lengths 
     33of the atoms constituting the solvent molecules respectively, and $v_p$ and 
     34$v_s$ are the partial molar volume of the polymer and the solvent respectively 
     35 
     36$L_b$ is the Bjerrum length(|Ang|) - **Note:** This parameter needs to be 
     37kept constant for a given solvent and temperature! 
     38 
     39$h$ is the virial parameter (|Ang^3|/mol) - **Note:** See [#Borue]_ for the 
     40correct interpretation of this parameter.  It incorporates second and third 
     41virial coefficients and can be Negative. 
     42 
     43$b$ is the monomer length(|Ang|), $C_s$ is the concentration of monovalent 
     44salt(mol/L), $\alpha$ is the ionization degree (ionization degree : ratio of 
     45charged monomers  to total number of monomers), $C_a$ is the polymer molar 
     46concentration(mol/L), and $background$ is the incoherent background. 
    5847 
    5948For 2D data the scattering intensity is calculated in the same way as 1D, 
     
    6352 
    6453    q = \sqrt{q_x^2 + q_y^2} 
    65  
    66 Validation 
    67 ---------- 
    68  
    69 As of the last revision, this code is believed to be correct.  However it 
    70 needs further validation and should be used with caution at this time.  The 
    71 history of this code goes back to a 1998 implementation. It was recently noted 
    72 that in that implementation, while both the polymer concentration and salt 
    73 concentration were converted from experimental units of mol/L to more 
    74 dimensionally useful units of 1/|Ang^3|, only the converted version of the 
    75 polymer concentration was actually being used in the calculation while the 
    76 unconverted salt concentration (still in apparent units of mol/L) was being  
    77 used.  This was carried through to Sasmodels as used for SasView 4.1 (though  
    78 the line of code converting the salt concentration to the new units was removed  
    79 somewhere along the line). Simple dimensional analysis of the calculation shows  
    80 that the converted salt concentration should be used, which the original code  
    81 suggests was the intention, so this has now been corrected (for SasView 4.2).  
    82 Once better validation has been performed this note will be removed. 
    8354 
    8455References 
     
    9566 
    9667* **Author:** NIST IGOR/DANSE **Date:** pre 2010 
    97 * **Last Modified by:** Paul Butler **Date:** September 25, 2018 
    98 * **Last Reviewed by:** Paul Butler **Date:** September 25, 2018 
     68* **Last Modified by:** Paul Kienzle **Date:** July 24, 2016 
     69* **Last Reviewed by:** Paul Butler and Richard Heenan **Date:** October 07, 2016 
    9970""" 
    10071 
     
    12192    ["contrast_factor",       "barns",   10.0,  [-inf, inf], "", "Contrast factor of the polymer"], 
    12293    ["bjerrum_length",        "Ang",      7.1,  [0, inf],    "", "Bjerrum length"], 
    123     ["virial_param",          "Ang^3", 12.0,  [-inf, inf], "", "Virial parameter"], 
     94    ["virial_param",          "Ang^3/mol", 12.0,  [-inf, inf], "", "Virial parameter"], 
    12495    ["monomer_length",        "Ang",     10.0,  [0, inf],    "", "Monomer length"], 
    12596    ["salt_concentration",    "mol/L",    0.0,  [-inf, inf], "", "Concentration of monovalent salt"], 
     
    131102 
    132103def Iq(q, 
    133        contrast_factor, 
    134        bjerrum_length, 
    135        virial_param, 
    136        monomer_length, 
    137        salt_concentration, 
    138        ionization_degree, 
    139        polymer_concentration): 
     104       contrast_factor=10.0, 
     105       bjerrum_length=7.1, 
     106       virial_param=12.0, 
     107       monomer_length=10.0, 
     108       salt_concentration=0.0, 
     109       ionization_degree=0.05, 
     110       polymer_concentration=0.7): 
    140111    """ 
    141     :params: see parameter table 
    142     :return: 1-D form factor for polyelectrolytes in low salt 
    143      
    144     parameter names, units, default values, and behavior (volume, sld etc) are 
    145     defined in the parameter table.  The concentrations are converted from 
    146     experimental mol/L to dimensionaly useful 1/A3 in first two lines 
     112    :param q:                     Input q-value 
     113    :param contrast_factor:       Contrast factor of the polymer 
     114    :param bjerrum_length:        Bjerrum length 
     115    :param virial_param:          Virial parameter 
     116    :param monomer_length:        Monomer length 
     117    :param salt_concentration:    Concentration of monovalent salt 
     118    :param ionization_degree:     Degree of ionization 
     119    :param polymer_concentration: Polymer molar concentration 
     120    :return:                      1-D intensity 
    147121    """ 
    148122 
    149     concentration_pol = polymer_concentration * 6.022136e-4 
    150     concentration_salt = salt_concentration * 6.022136e-4 
    151  
    152     k_square = 4.0 * pi * bjerrum_length * (2*concentration_salt + 
    153                                             ionization_degree * concentration_pol) 
    154  
    155     r0_square = 1.0/ionization_degree/sqrt(concentration_pol) * \ 
     123    concentration = polymer_concentration * 6.022136e-4 
     124 
     125    k_square = 4.0 * pi * bjerrum_length * (2*salt_concentration + 
     126                                            ionization_degree * concentration) 
     127 
     128    r0_square = 1.0/ionization_degree/sqrt(concentration) * \ 
    156129                (monomer_length/sqrt((48.0*pi*bjerrum_length))) 
    157130 
     
    160133 
    161134    term2 = 1.0 + r0_square**2 * (q**2 + k_square) * \ 
    162         (q**2 - (12.0 * virial_param * concentration_pol/(monomer_length**2))) 
     135        (q**2 - (12.0 * virial_param * concentration/(monomer_length**2))) 
    163136 
    164137    return term1/term2 
     
    201174 
    202175    # Accuracy tests based on content in test/utest_other_models.py 
    203     # Note that these should some day be validated beyond this self validation 
    204     # (circular reasoning). -- i.e. the "good value," at least for those with 
    205     # non zero salt concentrations, were obtained by running the current 
    206     # model in SasView and copying the appropriate result here. 
    207     #    PDB -- Sep 26, 2018 
    208176    [{'contrast_factor':       10.0, 
    209177      'bjerrum_length':         7.1, 
     
    216184     }, 0.001, 0.0948379], 
    217185 
     186    # Additional tests with larger range of parameters 
    218187    [{'contrast_factor':       10.0, 
    219188      'bjerrum_length':       100.0, 
    220189      'virial_param':           3.0, 
    221       'monomer_length':         5.0, 
    222       'salt_concentration':     1.0, 
    223       'ionization_degree':      0.1, 
    224       'polymer_concentration':  1.0, 
     190      'monomer_length':         1.0, 
     191      'salt_concentration':    10.0, 
     192      'ionization_degree':      2.0, 
     193      'polymer_concentration': 10.0, 
    225194      'background':             0.0, 
    226      }, 0.1, 0.253469484], 
     195     }, 0.1, -3.75693800588], 
    227196 
    228197    [{'contrast_factor':       10.0, 
    229198      'bjerrum_length':       100.0, 
    230199      'virial_param':           3.0, 
    231       'monomer_length':         5.0, 
    232       'salt_concentration':     1.0, 
    233       'ionization_degree':      0.1, 
    234       'polymer_concentration':  1.0, 
    235       'background':             1.0, 
    236      }, 0.05, 1.738358122], 
     200      'monomer_length':         1.0, 
     201      'salt_concentration':    10.0, 
     202      'ionization_degree':      2.0, 
     203      'polymer_concentration': 10.0, 
     204      'background':           100.0 
     205     }, 5.0, 100.029142149], 
    237206 
    238207    [{'contrast_factor':     100.0, 
    239208      'bjerrum_length':       10.0, 
    240       'virial_param':         12.0, 
    241       'monomer_length':       10.0, 
     209      'virial_param':        180.0, 
     210      'monomer_length':        1.0, 
    242211      'salt_concentration':    0.1, 
    243212      'ionization_degree':     0.5, 
    244213      'polymer_concentration': 0.1, 
    245       'background':           0.01, 
    246      }, 0.5, 0.012881893], 
     214      'background':             0.0, 
     215     }, 200., 1.80664667511e-06], 
    247216    ] 
  • sasmodels/models/fcc_paracrystal.py

    rda7b26b re7e9231  
    33#note - calculation requires double precision 
    44r""" 
    5 .. warning:: This model and this model description are under review following 
    6              concerns raised by SasView users. If you need to use this model, 
    7              please email help@sasview.org for the latest situation. *The 
    8              SasView Developers. September 2018.* 
    9  
    105Definition 
    116---------- 
     
    1510negligible, and the size of the paracrystal is infinitely large. 
    1611Paracrystalline distortion is assumed to be isotropic and characterized by 
    17 a Gaussian distribution. 
     12a Gaussian distribution.  
    1813 
    1914The scattering intensity $I(q)$ is calculated as 
  • sasmodels/models/sc_paracrystal.py

    rda7b26b r0b906ea  
    11r""" 
    2 .. warning:: This model and this model description are under review following 
    3              concerns raised by SasView users. If you need to use this model, 
    4              please email help@sasview.org for the latest situation. *The 
    5              SasView Developers. September 2018.* 
    6  
    72Definition 
    83---------- 
     
    149by a Gaussian distribution. 
    1510 
    16 The scattering intensity $I(q)$ is calculated as 
     11he scattering intensity $I(q)$ is calculated as 
    1712 
    1813.. math:: 
     
    2621 
    2722Equation (16) of the 1987 reference\ [#CIT1987]_ is used to calculate $Z(q)$, 
    28 using equations (13)-(15) from the 1987 paper\ [#CIT1987]_ for $Z1$, $Z2$, and 
    29 $Z3$. 
     23using equations (13)-(15) from the 1987 paper\ [#CIT1987]_ for Z1, Z2, and Z3. 
    3024 
    3125The lattice correction (the occupied volume of the lattice) for a simple cubic 
  • sasmodels/models/spinodal.py

    r93fe8a1 r475ff58  
    1212where $x=q/q_0$, $q_0$ is the peak position, $I_{max}$ is the intensity  
    1313at $q_0$ (parameterised as the $scale$ parameter), and $B$ is a flat  
    14 background. The spinodal wavelength, $\Lambda$, is given by $2\pi/q_0$.  
    15  
    16 The definition of $I_{max}$ in the literature varies. Hashimoto *et al* (1991)  
    17 define it as  
    18  
    19 .. math:: 
    20     I_{max} = \Lambda^3\Delta\rho^2 
    21      
    22 whereas Meier & Strobl (1987) give  
    23  
    24 .. math:: 
    25     I_{max} = V_z\Delta\rho^2 
    26      
    27 where $V_z$ is the volume per monomer unit. 
     14background. The spinodal wavelength is given by $2\pi/q_0$.  
    2815 
    2916The exponent $\gamma$ is equal to $d+1$ for off-critical concentration  
     
    4128 
    4229H. Furukawa. Dynamics-scaling theory for phase-separating unmixing mixtures: 
    43 Growth rates of droplets and scaling properties of autocorrelation functions.  
    44 Physica A 123, 497 (1984). 
    45  
    46 H. Meier & G. Strobl. Small-Angle X-ray Scattering Study of Spinodal  
    47 Decomposition in Polystyrene/Poly(styrene-co-bromostyrene) Blends.  
    48 Macromolecules 20, 649-654 (1987). 
    49  
    50 T. Hashimoto, M. Takenaka & H. Jinnai. Scattering Studies of Self-Assembling  
    51 Processes of Polymer Blends in Spinodal Decomposition.  
    52 J. Appl. Cryst. 24, 457-466 (1991). 
     30Growth rates of droplets and scaling properties of autocorrelation functions. 
     31Physica A 123,497 (1984). 
    5332 
    5433Revision History 
     
    5635 
    5736* **Author:**  Dirk Honecker **Date:** Oct 7, 2016 
    58 * **Revised:** Steve King    **Date:** Oct 25, 2018 
     37* **Revised:** Steve King    **Date:** Sep 7, 2018 
    5938""" 
    6039 
  • sasmodels/sasview_model.py

    rbd547d0 rd533590  
    6262#: set of defined models (standard and custom) 
    6363MODELS = {}  # type: Dict[str, SasviewModelType] 
    64 # TODO: remove unused MODEL_BY_PATH cache once sasview no longer references it 
    6564#: custom model {path: model} mapping so we can check timestamps 
    6665MODEL_BY_PATH = {}  # type: Dict[str, SasviewModelType] 
    67 #: Track modules that we have loaded so we can determine whether the model 
    68 #: has changed since we last reloaded. 
    69 _CACHED_MODULE = {}  # type: Dict[str, "module"] 
    7066 
    7167def find_model(modelname): 
     
    110106    Load a custom model given the model path. 
    111107    """ 
     108    model = MODEL_BY_PATH.get(path, None) 
     109    if model is not None and model.timestamp == getmtime(path): 
     110        #logger.info("Model already loaded %s", path) 
     111        return model 
     112 
    112113    #logger.info("Loading model %s", path) 
    113  
    114     # Load the kernel module.  This may already be cached by the loader, so 
    115     # only requires checking the timestamps of the dependents. 
    116114    kernel_module = custom.load_custom_kernel_module(path) 
    117  
    118     # Check if the module has changed since we last looked. 
    119     reloaded = kernel_module != _CACHED_MODULE.get(path, None) 
    120     _CACHED_MODULE[path] = kernel_module 
    121  
    122     # Turn the module into a model.  We need to do this in even if the 
    123     # model has already been loaded so that we can determine the model 
    124     # name and retrieve it from the MODELS cache. 
    125     model = getattr(kernel_module, 'Model', None) 
    126     if model is not None: 
     115    if hasattr(kernel_module, 'Model'): 
     116        model = kernel_module.Model 
    127117        # Old style models do not set the name in the class attributes, so 
    128118        # set it here; this name will be overridden when the object is created 
     
    137127        model_info = modelinfo.make_model_info(kernel_module) 
    138128        model = make_model_from_info(model_info) 
     129    model.timestamp = getmtime(path) 
    139130 
    140131    # If a model name already exists and we are loading a different model, 
     
    152143                    _previous_name, model.name, model.filename) 
    153144 
    154     # Only update the model if the module has changed 
    155     if reloaded or model.name not in MODELS: 
    156         MODELS[model.name] = model 
    157  
    158     return MODELS[model.name] 
     145    MODELS[model.name] = model 
     146    MODEL_BY_PATH[path] = model 
     147    return model 
    159148 
    160149 
     
    383372            hidden.add('background') 
    384373            self._model_info.parameters.defaults['background'] = 0. 
    385  
    386         # Update the parameter lists to exclude any hidden parameters 
    387         self.magnetic_params = tuple(pname for pname in self.magnetic_params 
    388                                      if pname not in hidden) 
    389         self.orientation_params = tuple(pname for pname in self.orientation_params 
    390                                         if pname not in hidden) 
    391374 
    392375        self._persistency_dict = {} 
     
    803786            return value, [value], [1.0] 
    804787 
    805     @classmethod 
    806     def runTests(cls): 
    807         """ 
    808         Run any tests built into the model and captures the test output. 
    809  
    810         Returns success flag and output 
    811         """ 
    812         from .model_test import check_model 
    813         return check_model(cls._model_info) 
    814  
    815788def test_cylinder(): 
    816789    # type: () -> float 
     
    900873    Model = _make_standard_model('sphere') 
    901874    model = Model() 
    902     model.setParam('sld_M0', 8) 
     875    model.setParam('M0:sld', 8) 
    903876    q = np.linspace(-0.35, 0.35, 500) 
    904877    qx, qy = np.meshgrid(q, q) 
  • sasmodels/special.py

    rfba9ca0 rdf69efa  
    113113        The standard math function, tgamma(x) is unstable for $x < 1$ 
    114114        on some platforms. 
    115  
    116     sas_gammaln(x): 
    117         log gamma function sas_gammaln\ $(x) = \log \Gamma(|x|)$. 
    118  
    119         The standard math function, lgamma(x), is incorrect for single 
    120         precision on some platforms. 
    121  
    122     sas_gammainc(a, x), sas_gammaincc(a, x): 
    123         Incomplete gamma function 
    124         sas_gammainc\ $(a, x) = \int_0^x t^{a-1}e^{-t}\,dt / \Gamma(a)$ 
    125         and complementary incomplete gamma function 
    126         sas_gammaincc\ $(a, x) = \int_x^\infty t^{a-1}e^{-t}\,dt / \Gamma(a)$ 
    127115 
    128116    sas_erf(x), sas_erfc(x): 
     
    219207from numpy import pi, nan, inf 
    220208from scipy.special import gamma as sas_gamma 
    221 from scipy.special import gammaln as sas_gammaln 
    222 from scipy.special import gammainc as sas_gammainc 
    223 from scipy.special import gammaincc as sas_gammaincc 
    224209from scipy.special import erf as sas_erf 
    225210from scipy.special import erfc as sas_erfc 
  • setup.py

    r783e76f r1f991d6  
    2929                return version[1:-1] 
    3030    raise RuntimeError("Could not read version from %s/__init__.py"%package) 
    31  
    32 install_requires = ['numpy', 'scipy'] 
    33  
    34 if sys.platform=='win32' or sys.platform=='cygwin': 
    35     install_requires.append('tinycc') 
    3631 
    3732setup( 
     
    6661        'sasmodels': ['*.c', '*.cl'], 
    6762    }, 
    68     install_requires=install_requires, 
     63    install_requires=[ 
     64    ], 
    6965    extras_require={ 
    70         'full': ['docutils', 'bumps', 'matplotlib'], 
    71         'server': ['bumps'], 
    7266        'OpenCL': ["pyopencl"], 
     67        'Bumps': ["bumps"], 
     68        'TinyCC': ["tinycc"], 
    7369    }, 
    7470    build_requires=['setuptools'], 
Note: See TracChangeset for help on using the changeset viewer.