Changes in sasmodels/modelinfo.py [39a06c9:d8eaa3d] in sasmodels


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/modelinfo.py

    r39a06c9 rd8eaa3d  
    290290    example, might be used to set the value of a shape parameter. 
    291291 
    292     These values are set by :func:`make_parameter_table` and 
     292    Control parameters are used for variant models such as :ref:`rpa` which 
     293    have different cases with different parameters, as well as models 
     294    like :ref:`spherical_sld` with its user defined number of shells. 
     295    The control parameter should appear in the parameter table along with the 
     296    parameters it is is controlling.  For variant models, use *[CASES]* in 
     297    place of the parameter limits Within the parameter definition table, 
     298    with case names such as:: 
     299 
     300         CASES = ["diblock copolymer", "triblock copolymer", ...] 
     301 
     302    This should give *limits=[[case1, case2, ...]]*, but the model loader 
     303    translates it to *limits=[0, len(CASES)-1]*, and adds *choices=CASES* to 
     304    the :class:`Parameter` definition. Note that models can use a list of 
     305    cases as a parameter without it being a control parameter.  Either way, 
     306    the parameter is sent to the model evaluator as *float(choice_num)*, 
     307    where choices are numbered from 0. :meth:`ModelInfo.get_hidden_parameters` 
     308    will determine which parameers to display. 
     309 
     310    The class contructor should not be called directly, but instead the 
     311    parameter table is built using :func:`make_parameter_table` and 
    293312    :func:`parse_parameter` therein. 
    294313    """ 
     
    404423      parameters counted as n individual parameters p1, p2, ... 
    405424 
     425    * *common_parameters* is the list of common parameters, with a unique 
     426      copy for each model so that structure factors can have a default 
     427      background of 0.0. 
     428 
    406429    * *call_parameters* is the complete list of parameters to the kernel, 
    407430      including scale and background, with vector parameters recorded as 
     
    416439    parameters don't use vector notation, and instead use p1, p2, ... 
    417440    """ 
    418     # scale and background are implicit parameters 
    419     COMMON = [Parameter(*p) for p in COMMON_PARAMETERS] 
    420  
    421441    def __init__(self, parameters): 
    422442        # type: (List[Parameter]) -> None 
     443 
     444        # scale and background are implicit parameters 
     445        # Need them to be unique to each model in case they have different 
     446        # properties, such as default=0.0 for structure factor backgrounds. 
     447        self.common_parameters = [Parameter(*p) for p in COMMON_PARAMETERS] 
     448 
    423449        self.kernel_parameters = parameters 
    424450        self._set_vector_lengths() 
     
    468494                         if p.polydisperse and p.type not in ('orientation', 'magnetic')) 
    469495        self.pd_2d = set(p.name for p in self.call_parameters if p.polydisperse) 
     496 
     497    def set_zero_background(self): 
     498        """ 
     499        Set the default background to zero for this model.  This is done for 
     500        structure factor models. 
     501        """ 
     502        # type: () -> None 
     503        # Make sure background is the second common parameter. 
     504        assert self.common_parameters[1].id == "background" 
     505        self.common_parameters[1].default = 0.0 
     506        self.defaults = self._get_defaults() 
    470507 
    471508    def check_angles(self): 
     
    567604    def _get_call_parameters(self): 
    568605        # type: () -> List[Parameter] 
    569         full_list = self.COMMON[:] 
     606        full_list = self.common_parameters[:] 
    570607        for p in self.kernel_parameters: 
    571608            if p.length == 1: 
     
    670707 
    671708        # Gather the user parameters in order 
    672         result = control + self.COMMON 
     709        result = control + self.common_parameters 
    673710        for p in self.kernel_parameters: 
    674711            if not is2d and p.type in ('orientation', 'magnetic'): 
     
    770807 
    771808    info = ModelInfo() 
     809 
     810    # Build the parameter table 
    772811    #print("make parameter table", kernel_module.parameters) 
    773812    parameters = make_parameter_table(getattr(kernel_module, 'parameters', [])) 
     813 
     814    # background defaults to zero for structure factor models 
     815    structure_factor = getattr(kernel_module, 'structure_factor', False) 
     816    if structure_factor: 
     817        parameters.set_zero_background() 
     818 
     819    # TODO: remove demo parameters 
     820    # The plots in the docs are generated from the model default values. 
     821    # Sascomp set parameters from the command line, and so doesn't need 
     822    # demo values for testing. 
    774823    demo = expand_pars(parameters, getattr(kernel_module, 'demo', None)) 
     824 
    775825    filename = abspath(kernel_module.__file__).replace('.pyc', '.py') 
    776826    kernel_id = splitext(basename(filename))[0] 
     
    814864    info.single = getattr(kernel_module, 'single', not callable(info.Iq)) 
    815865    info.random = getattr(kernel_module, 'random', None) 
    816  
    817     # multiplicity info 
    818     control_pars = [p.id for p in parameters.kernel_parameters if p.is_control] 
    819     default_control = control_pars[0] if control_pars else None 
    820     info.control = getattr(kernel_module, 'control', default_control) 
    821866    info.hidden = getattr(kernel_module, 'hidden', None) # type: ignore 
     867 
     868    # Set control flag for explicitly set parameters, e.g., in the RPA model. 
     869    control = getattr(kernel_module, 'control', None) 
     870    if control is not None: 
     871        parameters[control].is_control = True 
    822872 
    823873    if callable(info.Iq) and parameters.has_2d: 
     
    872922    #: *sphere*hardsphere* or *cylinder+sphere*. 
    873923    composition = None      # type: Optional[Tuple[str, List[ModelInfo]]] 
    874     #: Name of the control parameter for a variant model such as :ref:`rpa`. 
    875     #: The *control* parameter should appear in the parameter table, with 
    876     #: limits defined as *[CASES]*, for case names such as 
    877     #: *CASES = ["diblock copolymer", "triblock copolymer", ...]*. 
    878     #: This should give *limits=[[case1, case2, ...]]*, but the 
    879     #: model loader translates this to *limits=[0, len(CASES)-1]*, and adds 
    880     #: *choices=CASES* to the :class:`Parameter` definition. Note that 
    881     #: models can use a list of cases as a parameter without it being a 
    882     #: control parameter.  Either way, the parameter is sent to the model 
    883     #: evaluator as *float(choice_num)*, where choices are numbered from 0. 
    884     #: See also :attr:`hidden`. 
    885     control = None          # type: str 
    886924    #: Different variants require different parameters.  In order to show 
    887925    #: just the parameters needed for the variant selected by :attr:`control`, 
     
    947985    #: C code, either defined as a string, or in the sources. 
    948986    shell_volume = None      # type: Union[None, str, Callable[[np.ndarray], float]] 
     987    #: Computes the effective radius of the shape given the volume parameters. 
     988    #: Only needed for models defined in python that can be used for 
     989    #: monodisperse approximation for non-dilute solutions, P@S.  The first 
     990    #: argument is the integer effective radius mode, with default 0. 
     991    effective_radius = None  # type: Union[None, Callable[[int, np.ndarray], float]] 
    949992    #: Returns *I(q, a, b, ...)* for parameters *a*, *b*, etc. defined 
    950993    #: by the parameter table.  *Iq* can be defined as a python function, or 
     
    9581001    #: will return *I(q, a, b, ...)*.  Multiplicity parameters are sent as 
    9591002    #: pointers to doubles.  Constants in floating point expressions should 
    960     #: include the decimal point. See :mod:`generate` for more details. 
     1003    #: include the decimal point. See :mod:`generate` for more details. If 
     1004    #: *have_Fq* is True, then Iq should return an interleaved array of 
     1005    #: $[\sum F(q_1), \sum F^2(q_1), \ldots, \sum F(q_n), \sum F^2(q_n)]$. 
    9611006    Iq = None               # type: Union[None, str, Callable[[np.ndarray], np.ndarray]] 
    9621007    #: Returns *I(qab, qc, a, b, ...)*.  The interface follows :attr:`Iq`. 
Note: See TracChangeset for help on using the changeset viewer.