Changeset 04045f4 in sasmodels
- Timestamp:
- Apr 12, 2016 8:02:40 PM (9 years ago)
- 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:
- 793beb3
- Parents:
- fa5fd8d
- Location:
- sasmodels
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/modelinfo.py
r7ae2b7f r04045f4 7 7 module into the model info block as seen by the rest of the sasmodels library. 8 8 """ 9 from __future__ import print_function 10 9 11 from copy import copy 10 12 from os.path import abspath, basename, splitext … … 16 18 # Optional typing 17 19 try: 18 from typing import Tuple, List, Union, Dict, Optional, Any, Callable 20 from typing import Tuple, List, Union, Dict, Optional, Any, Callable, Sequence, Set 19 21 except ImportError: 20 22 pass … … 22 24 from .details import CallDetails 23 25 Limits = Tuple[float, float] 24 #LimitsOrChoice = Union[Limits, Tuple[str]]26 LimitsOrChoice = Union[Limits, Tuple[Sequence[str]]] 25 27 ParameterDef = Tuple[str, str, float, Limits, str, str] 26 28 ParameterSetUser = Dict[str, Union[float, List[float]]] … … 68 70 69 71 def parse_parameter(name, units='', default=np.NaN, 70 limits=(-np.inf, np.inf), ptype='', description=''):71 # type: (str, str, float, Limits , str, str) -> Parameter72 user_limits=None, ptype='', description=''): 73 # type: (str, str, float, LimitsOrChoice, str, str) -> Parameter 72 74 """ 73 75 Parse an individual parameter from the parameter definition block. … … 81 83 if not isstr(units): 82 84 raise ValueError("expected units to be a string for %s"%name) 83 # if limits is a list of strings, then this is a choice list 84 # field, and limits are 1 to length of string list85 86 # Process limits as [float, float] or [[str, str, ...]] 85 87 choices = [] # type: List[str] 86 if isinstance(limits, list) and all(isstr(k) for k in limits): 87 choices = limits 88 limits = (0., len(choices)-1.) 89 90 # TODO: maybe allow limits of None for (-inf, inf) 91 try: 92 low, high = limits 93 if not isinstance(low, (int, float)): 94 raise TypeError("low is not numeric") 95 if not isinstance(high, (int, float)): 96 raise TypeError("high is not numeric") 97 if low >= high: 98 raise ValueError("require low < high") 99 except Exception: 100 raise ValueError("invalid limits %s for %s"%(limits, name)) 101 88 if user_limits is None: 89 limits = (-np.inf, np.inf) 90 elif not isinstance(user_limits, (tuple, list)): 91 raise ValueError("invalid limits for %s"%name) 92 else: 93 # if limits is [[str,...]], then this is a choice list field, 94 # and limits are 1 to length of string list 95 if isinstance(user_limits[0], (tuple, list)): 96 choices = user_limits[0] 97 limits = (0., len(choices)-1.) 98 if not all(isstr(k) for k in choices): 99 raise ValueError("choices must be strings for %s"%name) 100 else: 101 try: 102 low, high = user_limits 103 limits = (float(low), float(high)) 104 except Exception: 105 raise ValueError("invalid limits for %s"%name) 106 else: 107 if low >= high: 108 raise ValueError("require lower limit < upper limit") 109 110 # Process default value as float, making sure it is in range 102 111 if not isinstance(default, (int, float)): 103 112 raise ValueError("expected default %r to be a number for %s" 104 113 % (default, name)) 105 if default < l ow or default > high:114 if default < limits[0] or default > limits[1]: 106 115 raise ValueError("default value %r not in range for %s" 107 116 % (default, name)) 108 117 118 # Check for valid parameter type 109 119 if ptype not in ("volume", "orientation", "sld", "magnetic", ""): 110 120 raise ValueError("unexpected type %r for %s" % (ptype, name)) 111 121 122 # Check for valid parameter description 112 123 if not isstr(description): 113 124 raise ValueError("expected description to be a string") 114 115 125 116 126 # Parameter id for name[n] does not include [n] … … 122 132 else: 123 133 pid, ref = name, None 124 125 134 126 135 # automatically identify sld types … … 474 483 raise ValueError("expected limits on %s to be within [0, 20]" 475 484 % ref.name) 476 # TODO: may want to make a copy of the parameter before updating 477 # this introduces other potential problems, since the same 478 # parameter may be referenced elsewhere 479 p.length = high 485 p.length = int(high) 480 486 481 487 def _get_defaults(self): … … 544 550 early, and rerender the table when it is changed. 545 551 """ 552 # control parameters go first 546 553 control = [p for p in self.kernel_parameters if p.is_control] 547 554 548 555 # Gather entries such as name[n] into groups of the same n 549 dependent = dict((p.id, []) for p in control) # type: Dict[str, List[Parameter]] 556 dependent = {} # type: Dict[str, List[Parameter]] 557 dependent.update((p.id, []) for p in control) 550 558 for p in self.kernel_parameters: 551 559 if p.length_control is not None: … … 635 643 info.single = getattr(kernel_module, 'single', True) 636 644 info.structure_factor = getattr(kernel_module, 'structure_factor', False) 637 info.profile_axes = getattr(kernel_module, 'profile_axes', ['x', 'y'])645 info.profile_axes = getattr(kernel_module, 'profile_axes', ['x', 'y']) 638 646 info.variant_info = getattr(kernel_module, 'variant_info', None) 639 647 info.source = getattr(kernel_module, 'source', []) … … 647 655 info.profile = getattr(kernel_module, 'profile', None) # type: ignore 648 656 info.sesans = getattr(kernel_module, 'sesans', None) # type: ignore 657 info.control = getattr(kernel_module, 'control', None) 658 info.hidden = getattr(kernel_module, 'hidden', None) # type: ignore 649 659 650 660 # Precalculate the monodisperse parameter details … … 691 701 *model_info* blocks for the composition objects. This allows us to 692 702 build complete product and mixture models from just the info. 703 * *control* is the name of the control parameter if there is one. 704 * *hidden* returns the list of hidden parameters given the value of the 705 control parameter 693 706 694 707 The structure should be mostly static, other than the delayed definition … … 703 716 demo = None # type: Dict[str, float] 704 717 composition = None # type: Optional[Tuple[str, List[ModelInfo]]] 718 control = None # type: str 705 719 docs = None # type: str 706 720 category = None # type: Optional[str] … … 718 732 profile = None # type: Optional[Callable[[np.ndarray], None]] 719 733 sesans = None # type: Optional[Callable[[np.ndarray], np.ndarray]] 734 hidden = None # type: Optional[Callable[int], Set[str]] 720 735 mono_details = None # type: CallDetails 721 736 … … 724 739 pass 725 740 726 741 def get_hidden_parameters(self, control): 742 if self.hidden is not None: 743 hidden = self.hidden(control) 744 else: 745 controls = [p for p in self.parameters.kernel_parameters] 746 if len(controls) != 1: 747 raise ValueError("more than one control parameter") 748 hidden = set(p.id+str(k) 749 for p in self.parameters.kernel_parameters 750 for k in range(control+1, p.length+1) 751 if p.length > 1) 752 return hidden -
sasmodels/sasview_model.py
rfa5fd8d r04045f4 124 124 #self.is_multifunc = False 125 125 non_fittable = [] # type: List[str] 126 xlabel = model_info.profile_axes[0] if model_info.profile is not None else "" 127 variants = MultiplicityInfo(0, "", [], xlabel) 126 128 for p in parameters.kernel_parameters: 127 if p. is_control:129 if p.name == model_info.control: 128 130 non_fittable.append(p.name) 129 profile_axes = model_info.profile_axes 130 multiplicity_info = MultiplicityInfo( 131 p.limits[1], p.name, p.choices, profile_axes[0] 131 variants = MultiplicityInfo( 132 len(p.choices), p.name, p.choices, xlabel 132 133 ) 133 134 break 134 else: 135 multiplicity_info = MultiplicityInfo(0, "", [], "") 135 elif p.is_control: 136 non_fittable.append(p.name) 137 variants = MultiplicityInfo( 138 int(p.limits[1]), p.name, p.choices, xlabel 139 ) 140 break 136 141 137 142 attrs['is_structure_factor'] = model_info.structure_factor 138 143 attrs['is_form_factor'] = model_info.ER is not None 139 attrs['is_multiplicity_model'] = multiplicity_info[0] > 1 140 attrs['multiplicity_info'] = multiplicity_info 141 144 attrs['is_multiplicity_model'] = variants[0] > 1 145 attrs['multiplicity_info'] = variants 142 146 143 147 orientation_params = [] … … 228 232 ## _persistency_dict is used by sas.perspectives.fitting.basepage 229 233 ## to store dispersity reference. 230 ## TODO: _persistency_dict to persistency_dict throughout sasview231 234 self._persistency_dict = {} 232 235 236 # TODO: _persistency_dict to persistency_dict throughout sasview 237 # TODO: refactor multiplicity to encompass variants 238 # TODO: dispersion should be a class 233 239 # TODO: refactor multiplicity info 234 240 # TODO: separate profile view from multiplicity … … 240 246 # and lines to plot. 241 247 242 # TODO: refactor multiplicity to encompass variants243 # TODO: dispersion should be a class248 # Get the list of hidden parameters given the mulitplicity 249 # Don't include multiplicity in the list of parameters 244 250 self.multiplicity = multiplicity 251 if multiplicity is not None: 252 hidden = self._model_info.get_hidden_parameters(multiplicity) 253 hidden |= set([self.multiplicity_info.control]) 254 else: 255 hidden = set() 256 245 257 self.params = collections.OrderedDict() 246 258 self.dispersion = {} 247 259 self.details = {} 248 config = ({self.multiplicity_info.control: multiplicity} 249 if multiplicity is not None else {}) 250 for p in self._model_info.parameters.user_parameters(config): 251 # Don't include multiplicity in the list of parameters 252 if p.name == self.multiplicity_info.control: 260 for p in self._model_info.parameters.user_parameters(): 261 if p.name in hidden: 253 262 continue 254 263 self.params[p.name] = p.default … … 601 610 return cylinder.evalDistribution([0.1,0.1]) 602 611 612 def test_rpa(): 613 # type: () -> float 614 """ 615 Test that a sasview model (cylinder) can be run. 616 """ 617 RPA = _make_standard_model('rpa') 618 rpa = RPA(3) 619 return rpa.evalDistribution([0.1,0.1]) 620 603 621 604 622 def test_model_list():
Note: See TracChangeset
for help on using the changeset viewer.