Changeset 04dc697 in sasmodels for sasmodels/bumps_model.py


Ignore:
Timestamp:
Apr 13, 2016 9:39:09 AM (8 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, costrafo411, magnetic_model, release_v0.94, release_v0.95, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
60f03de
Parents:
a18c5b3
Message:

more type hinting

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/bumps_model.py

    r7ae2b7f r04dc697  
    1111 
    1212""" 
    13  
    14 import warnings 
     13from __future__ import print_function 
     14 
     15__all__ = [ "Model", "Experiment" ] 
    1516 
    1617import numpy as np  # type: ignore 
     
    1920from .direct_model import DataMixin 
    2021 
    21 __all__ = [ 
    22     "Model", "Experiment", 
    23     ] 
    24  
    25 # CRUFT: old style bumps wrapper which doesn't separate data and model 
    26 # pylint: disable=invalid-name 
    27 def BumpsModel(data, model, cutoff=1e-5, **kw): 
    28     r""" 
    29     Bind a model to data, along with a polydispersity cutoff. 
    30  
    31     *data* is a :class:`data.Data1D`, :class:`data.Data2D` or 
    32     :class:`data.Sesans` object.  Use :func:`data.empty_data1D` or 
    33     :func:`data.empty_data2D` to define $q, \Delta q$ calculation 
    34     points for displaying the SANS curve when there is no measured data. 
    35  
    36     *model* is a runnable module as returned from :func:`core.load_model`. 
    37  
    38     *cutoff* is the polydispersity weight cutoff. 
    39  
    40     Any additional *key=value* pairs are model dependent parameters. 
    41  
    42     Returns an :class:`Experiment` object. 
    43  
    44     Note that the usual Bumps semantics is not fully supported, since 
    45     assigning *M.name = parameter* on the returned experiment object 
    46     does not set that parameter in the model.  Range setting will still 
    47     work as expected though. 
    48  
    49     .. deprecated:: 0.1 
    50         Use :class:`Experiment` instead. 
    51     """ 
    52     warnings.warn("Use of BumpsModel is deprecated.  Use bumps_model.Experiment instead.") 
    53  
    54     # Create the model and experiment 
    55     model = Model(model, **kw) 
    56     experiment = Experiment(data=data, model=model, cutoff=cutoff) 
    57  
    58     # Copy the model parameters up to the experiment object. 
    59     for k, v in model.parameters().items(): 
    60         setattr(experiment, k, v) 
    61     return experiment 
     22try: 
     23    from typing import Dict, Union, Tuple, Any 
     24    from .data import Data1D, Data2D 
     25    from .kernel import KernelModel 
     26    from .modelinfo import ModelInfo 
     27    Data = Union[Data1D, Data2D] 
     28except ImportError: 
     29    pass 
     30 
     31try: 
     32    # Optional import. This allows the doc builder and nosetests to run even 
     33    # when bumps is not on the path. 
     34    from bumps.names import Parameter # type: ignore 
     35except ImportError: 
     36    pass 
    6237 
    6338 
    6439def create_parameters(model_info, **kwargs): 
     40    # type: (ModelInfo, **Union[float, str, Parameter]) -> Tuple[Dict[str, Parameter], Dict[str, str]] 
    6541    """ 
    6642    Generate Bumps parameters from the model info. 
     
    7147    Any additional *key=value* pairs are initial values for the parameters 
    7248    to the models.  Uninitialized parameters will use the model default 
    73     value. 
     49    value.  The value can be a float, a bumps parameter, or in the case 
     50    of the distribution type parameter, a string. 
    7451 
    7552    Returns a dictionary of *{name: Parameter}* containing the bumps 
     
    7754    *{name: str}* containing the polydispersity distribution types. 
    7855    """ 
    79     # lazy import; this allows the doc builder and nosetests to run even 
    80     # when bumps is not on the path. 
    81     from bumps.names import Parameter  # type: ignore 
    82  
    83     pars = {}     # floating point parameters 
    84     pd_types = {} # distribution names 
     56    pars = {}     # type: Dict[str, Parameter] 
     57    pd_types = {} # type: Dict[str, str] 
    8558    for p in model_info.parameters.call_parameters: 
    8659        value = kwargs.pop(p.name, p.default) 
     
    9669                pars[name] = Parameter.default(value, name=name, limits=limits) 
    9770            name = p.name + '_pd_type' 
    98             pd_types[name] = kwargs.pop(name, 'gaussian') 
     71            pd_types[name] = str(kwargs.pop(name, 'gaussian')) 
    9972 
    10073    if kwargs:  # args not corresponding to parameters 
     
    11588    """ 
    11689    def __init__(self, model, **kwargs): 
    117         self._sasmodel = model 
     90        # type: (KernelModel, **Dict[str, Union[float, Parameter]]) -> None 
     91        self.sasmodel = model 
    11892        pars, pd_types = create_parameters(model.info, **kwargs) 
    11993        for k, v in pars.items(): 
     
    12599 
    126100    def parameters(self): 
     101        # type: () -> Dict[str, Parameter] 
    127102        """ 
    128103        Return a dictionary of parameters objects for the parameters, 
     
    132107 
    133108    def state(self): 
     109        # type: () -> Dict[str, Union[Parameter, str]] 
    134110        """ 
    135111        Return a dictionary of current values for all the parameters, 
     
    156132    The resulting model can be used directly in a Bumps FitProblem call. 
    157133    """ 
     134    _cache = None # type: Dict[str, np.ndarray] 
    158135    def __init__(self, data, model, cutoff=1e-5): 
    159  
     136        # type: (Data, Model, float) -> None 
    160137        # remember inputs so we can inspect from outside 
    161138        self.model = model 
    162139        self.cutoff = cutoff 
    163         self._interpret_data(data, model._sasmodel) 
    164         self.update() 
     140        self._interpret_data(data, model.sasmodel) 
     141        self._cache = {} 
    165142 
    166143    def update(self): 
     144        # type: () -> None 
    167145        """ 
    168146        Call when model parameters have changed and theory needs to be 
    169147        recalculated. 
    170148        """ 
    171         self._cache = {} 
     149        self._cache.clear() 
    172150 
    173151    def numpoints(self): 
     152        # type: () -> float 
    174153        """ 
    175154        Return the number of data points 
     
    178157 
    179158    def parameters(self): 
     159        # type: () -> Dict[str, Parameter] 
    180160        """ 
    181161        Return a dictionary of parameters 
     
    184164 
    185165    def theory(self): 
     166        # type: () -> np.ndarray 
    186167        """ 
    187168        Return the theory corresponding to the model parameters. 
     
    196177 
    197178    def residuals(self): 
     179        # type: () -> np.ndarray 
    198180        """ 
    199181        Return theory minus data normalized by uncertainty. 
     
    203185 
    204186    def nllf(self): 
     187        # type: () -> float 
    205188        """ 
    206189        Return the negative log likelihood of seeing data given the model 
     
    210193        delta = self.residuals() 
    211194        #if np.any(np.isnan(R)): print("NaN in residuals") 
    212         return 0.5 * np.sum(delta ** 2) 
     195        return 0.5 * np.sum(delta**2) 
    213196 
    214197    #def __call__(self): 
     
    216199 
    217200    def plot(self, view='log'): 
     201        # type: (str) -> None 
    218202        """ 
    219203        Plot the data and residuals. 
     
    223207 
    224208    def simulate_data(self, noise=None): 
     209        # type: (float) -> None 
    225210        """ 
    226211        Generate simulated data. 
     
    230215 
    231216    def save(self, basename): 
     217        # type: (str) -> None 
    232218        """ 
    233219        Save the model parameters and data into a file. 
     
    240226 
    241227    def __getstate__(self): 
     228        # type: () -> Dict[str, Any] 
    242229        # Can't pickle gpu functions, so instead make them lazy 
    243230        state = self.__dict__.copy() 
     
    246233 
    247234    def __setstate__(self, state): 
     235        # type: (Dict[str, Any]) -> None 
    248236        # pylint: disable=attribute-defined-outside-init 
    249237        self.__dict__ = state 
     238 
Note: See TracChangeset for help on using the changeset viewer.