Changeset 04045f4 in sasmodels for sasmodels/modelinfo.py
- Timestamp:
- Apr 12, 2016 6:02:40 PM (8 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
- File:
-
- 1 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
Note: See TracChangeset
for help on using the changeset viewer.