Changeset f0365a2e in sasview for src


Ignore:
Timestamp:
Sep 7, 2018 10:33:01 AM (6 years ago)
Author:
GitHub <noreply@…>
Branches:
ESS_GUI, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
Children:
9d23e4c, c0de493
Parents:
c2f3ca2 (diff), 5fb714b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Torin Cooper-Bennun <40573959+tcbennun@…> (09/07/18 10:33:01)
git-committer:
GitHub <noreply@…> (09/07/18 10:33:01)
Message:

Merge pull request #171 from SasView?/ESS_GUI_iss1032

SASVIEW-1032: Support for fixed-choice model parameters, e.g structure_factor_mode

Location:
src/sas/qtgui
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py

    r4ea8020 rb69b549  
    88from sas.qtgui.Plotting.PlotterData import Data1D 
    99from sas.qtgui.Plotting.PlotterData import Data2D 
     10 
     11from sas.qtgui.Perspectives.Fitting.AssociatedComboBox import AssociatedComboBox 
    1012 
    1113model_header_captions = ['Parameter', 'Value', 'Min', 'Max', 'Units'] 
     
    6163    return (param_name, param_length) 
    6264 
    63 def addParametersToModel(parameters, kernel_module, is2D): 
    64     """ 
    65     Update local ModelModel with sasmodel parameters 
     65def createFixedChoiceComboBox(param, item_row): 
     66    """ 
     67    Determines whether param is a fixed-choice parameter, modifies items in item_row appropriately and returns a combo 
     68    box containing the fixed choices. Returns None if param is not fixed-choice. 
     69     
     70    item_row is a list of QStandardItem objects for insertion into the parameter table.  
     71    """ 
     72 
     73    # Determine whether this is a fixed-choice parameter. There are lots of conditionals, simply because the 
     74    # implementation is not yet concrete; there are several possible indicators that the parameter is fixed-choice. 
     75    # TODO: (when the sasmodels implementation is concrete, clean this up) 
     76    choices = None 
     77    if isinstance(param.choices, (list, tuple)) and len(param.choices) > 0: 
     78        # The choices property is concrete in sasmodels, probably will use this 
     79        choices = param.choices 
     80    elif isinstance(param.units, (list, tuple)): 
     81        choices = [str(x) for x in param.units] 
     82 
     83    cbox = None 
     84    if choices is not None: 
     85        # Use combo box for input, if it is fixed-choice 
     86        cbox = AssociatedComboBox(item_row[1], idx_as_value=True) 
     87        cbox.addItems(choices) 
     88        item_row[2].setEditable(False) 
     89        item_row[3].setEditable(False) 
     90 
     91    return cbox 
     92 
     93def addParametersToModel(parameters, kernel_module, is2D, model=None, view=None): 
     94    """ 
     95    Update local ModelModel with sasmodel parameters. 
     96    Actually appends to model, if model and view params are not None. 
     97    Always returns list of lists of QStandardItems. 
    6698    """ 
    6799    multishell_parameters = getIterParams(parameters) 
     
    72104    else: 
    73105        params = parameters.iq_parameters 
    74     item = [] 
     106 
     107    rows = [] 
    75108    for param in params: 
    76109        # don't include shell parameters 
    77110        if param.name == multishell_param_name: 
    78111            continue 
     112 
    79113        # Modify parameter name from <param>[n] to <param>1 
    80114        item_name = param.name 
    81115        if param in multishell_parameters: 
    82116            continue 
    83         #    item_name = replaceShellName(param.name, 1) 
    84117 
    85118        item1 = QtGui.QStandardItem(item_name) 
    86119        item1.setCheckable(True) 
    87120        item1.setEditable(False) 
    88         # item_err = QtGui.QStandardItem() 
     121 
    89122        # check for polydisp params 
    90123        if param.polydisperse: 
     
    93126            item1_1 = QtGui.QStandardItem("Distribution") 
    94127            item1_1.setEditable(False) 
     128 
    95129            # Find param in volume_params 
    96130            for p in parameters.form_volume_parameters: 
     
    99133                width = kernel_module.getParam(p.name+'.width') 
    100134                ptype = kernel_module.getParam(p.name+'.type') 
    101  
    102135                item1_2 = QtGui.QStandardItem(str(width)) 
    103136                item1_2.setEditable(False) 
     
    110143                poly_item.appendRow([item1_1, item1_2, item1_3, item1_4, item1_5]) 
    111144                break 
     145 
    112146            # Add the polydisp item as a child 
    113147            item1.appendRow([poly_item]) 
     148 
    114149        # Param values 
    115150        item2 = QtGui.QStandardItem(str(param.default)) 
    116         # TODO: the error column. 
    117         # Either add a proxy model or a custom view delegate 
    118         #item_err = QtGui.QStandardItem() 
    119151        item3 = QtGui.QStandardItem(str(param.limits[0])) 
    120152        item4 = QtGui.QStandardItem(str(param.limits[1])) 
    121         item5 = QtGui.QStandardItem(param.units) 
     153        item5 = QtGui.QStandardItem(str(param.units)) 
    122154        item5.setEditable(False) 
    123         item.append([item1, item2, item3, item4, item5]) 
    124     return item 
    125  
    126 def addSimpleParametersToModel(parameters, is2D, parameters_original=None): 
    127     """ 
    128     Update local ModelModel with sasmodel parameters 
    129     parameters_original: list of parameters before any tagging on their IDs, e.g. for product model 
    130     (so that those are the display names; see below) 
     155 
     156        # Check if fixed-choice (returns combobox, if so, also makes some items uneditable) 
     157        row = [item1, item2, item3, item4, item5] 
     158        cbox = createFixedChoiceComboBox(param, row) 
     159 
     160        # Append to the model and use the combobox, if required 
     161        if None not in (model, view): 
     162            model.appendRow(row) 
     163            if cbox: 
     164                view.setIndexWidget(item2.index(), cbox) 
     165        rows.append(row) 
     166 
     167    return rows 
     168 
     169def addSimpleParametersToModel(parameters, is2D, parameters_original=None, model=None, view=None): 
     170    """ 
     171    Update local ModelModel with sasmodel parameters (non-dispersed, non-magnetic) 
     172    Actually appends to model, if model and view params are not None. 
     173    Always returns list of lists of QStandardItems. 
     174 
     175    parameters_original: list of parameters before any tagging on their IDs, e.g. for product model (so that those are 
     176    the display names; see below) 
    131177    """ 
    132178    if is2D: 
     
    147193        params_orig = params 
    148194 
    149     item = [] 
     195    rows = [] 
    150196    for param, param_orig in zip(params, params_orig): 
    151197        # Create the top level, checkable item 
     
    155201        item1.setCheckable(True) 
    156202        item1.setEditable(False) 
     203 
    157204        # Param values 
    158205        # TODO: add delegate for validation of cells 
    159206        item2 = QtGui.QStandardItem(str(param.default)) 
    160         item4 = QtGui.QStandardItem(str(param.limits[0])) 
    161         item5 = QtGui.QStandardItem(str(param.limits[1])) 
    162         item6 = QtGui.QStandardItem(str(param.units)) 
    163         item6.setEditable(False) 
    164         item.append([item1, item2, item4, item5, item6]) 
    165     return item 
     207        item3 = QtGui.QStandardItem(str(param.limits[0])) 
     208        item4 = QtGui.QStandardItem(str(param.limits[1])) 
     209        item5 = QtGui.QStandardItem(str(param.units)) 
     210        item5.setEditable(False) 
     211 
     212        # Check if fixed-choice (returns combobox, if so, also makes some items uneditable) 
     213        row = [item1, item2, item3, item4, item5] 
     214        cbox = createFixedChoiceComboBox(param, row) 
     215 
     216        # Append to the model and use the combobox, if required 
     217        if None not in (model, view): 
     218            model.appendRow(row) 
     219            if cbox: 
     220                view.setIndexWidget(item2.index(), cbox) 
     221        rows.append(row) 
     222 
     223    return rows 
    166224 
    167225def markParameterDisabled(model, row): 
     
    259317    model.header_tooltips = copy.copy(poly_header_error_tooltips) 
    260318 
    261 def addShellsToModel(parameters, model, index, row_num=None): 
     319def addShellsToModel(parameters, model, index, row_num=None, view=None): 
    262320    """ 
    263321    Find out multishell parameters and update the model with the requested number of them. 
    264322    Inserts them after the row at row_num, if not None; otherwise, appends to end. 
     323    If view param is not None, supports fixed-choice params. 
    265324    Returns a list of lists of QStandardItem objects. 
    266325    """ 
     
    285344                    item1_3 = QtGui.QStandardItem(str(p.limits[0])) 
    286345                    item1_4 = QtGui.QStandardItem(str(p.limits[1])) 
    287                     item1_5 = QtGui.QStandardItem(p.units) 
     346                    item1_5 = QtGui.QStandardItem(str(p.units)) 
    288347                    poly_item.appendRow([item1_1, item1_2, item1_3, item1_4, item1_5]) 
    289348                    break 
     
    293352            item3 = QtGui.QStandardItem(str(par.limits[0])) 
    294353            item4 = QtGui.QStandardItem(str(par.limits[1])) 
    295             item5 = QtGui.QStandardItem(par.units) 
     354            item5 = QtGui.QStandardItem(str(par.units)) 
     355            item5.setEditable(False) 
     356 
     357            # Check if fixed-choice (returns combobox, if so, also makes some items uneditable) 
    296358            row = [item1, item2, item3, item4, item5] 
    297             rows.append(row) 
    298  
     359            cbox = createFixedChoiceComboBox(par, row) 
     360 
     361            # Always add to the model 
    299362            if row_num is None: 
    300363                model.appendRow(row) 
     
    302365                model.insertRow(row_num, row) 
    303366                row_num += 1 
     367 
     368            # Apply combobox if required 
     369            if None not in (view, cbox): 
     370                view.setIndexWidget(item2.index(), cbox) 
     371 
     372            rows.append(row) 
    304373 
    305374    return rows 
  • src/sas/qtgui/Perspectives/Fitting/FittingWidget.py

    rc2f3ca2 rf0365a2e  
    20732073        self.shell_names = self.shellNamesList() 
    20742074 
    2075         # Get new rows for QModel 
    2076         new_rows = FittingUtilities.addParametersToModel(self.model_parameters, self.kernel_module, self.is2D) 
    2077  
    20782075        # Add heading row 
    20792076        FittingUtilities.addHeadingRowToModel(self._model_model, model_name) 
    20802077 
    2081         # Update QModel 
    2082         for row in new_rows: 
    2083             self._model_model.appendRow(row) 
     2078        # Update the QModel 
     2079        FittingUtilities.addParametersToModel( 
     2080                self.model_parameters, 
     2081                self.kernel_module, 
     2082                self.is2D, 
     2083                self._model_model, 
     2084                self.lstParams) 
    20842085 
    20852086    def fromStructureFactorToQModel(self, structure_factor): 
     
    20902091            return 
    20912092 
    2092         s_kernel = self.models[structure_factor]() 
    2093         p_kernel = self.kernel_module 
    2094  
    2095         if p_kernel is None: 
    2096             # Not a product model, just S(Q) 
    2097             self.kernel_module = s_kernel 
    2098             params = modelinfo.ParameterTable(self.kernel_module._model_info.parameters.kernel_parameters) 
    2099             new_rows = FittingUtilities.addSimpleParametersToModel(params, self.is2D) 
     2093        if self.kernel_module is None: 
     2094            # Structure factor is the only selected model; build it and show all its params 
     2095            self.kernel_module = self.models[structure_factor]() 
     2096            s_params = self.kernel_module._model_info.parameters 
     2097            s_params_orig = s_params 
     2098 
    21002099        else: 
     2100            s_kernel = self.models[structure_factor]() 
     2101            p_kernel = self.kernel_module 
     2102 
    21012103            p_pars_len = len(p_kernel._model_info.parameters.kernel_parameters) 
    21022104            s_pars_len = len(s_kernel._model_info.parameters.kernel_parameters) 
     
    21072109 
    21082110            # S(Q) params from the product model are not necessarily the same as those from the S(Q) model; any 
    2109             # conflicting names with P(Q) params will cause a rename; we also lose radius_effective (for now...) 
    2110  
    2111             # TODO: merge rest of beta approx implementation in 
    2112             # This is to ensure compatibility when we merge beta approx support in...! 
    2113  
    2114             # radius_effective is always s_params[0] 
    2115  
    2116             # if radius_effective_mode is in all_params, then all_params contains radius_effective and we want to 
    2117             # keep it in the model 
    2118  
    2119             # if radius_effective_mode is NOT in all_params, then radius_effective should NOT be kept, because the user 
    2120             # cannot specify it themselves; but, make sure we only remove it if it's actually there in the first place 
    2121             # (sasmodels master removes it already) 
     2111            # conflicting names with P(Q) params will cause a rename 
     2112 
    21222113            if "radius_effective_mode" in all_param_names: 
    21232114                # Show all parameters 
     
    21322123                    s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len-1]) 
    21332124 
    2134             # Get new rows for QModel 
    2135             # Any renamed parameters are stored as data in the relevant item, for later handling 
    2136             new_rows = FittingUtilities.addSimpleParametersToModel(s_params, self.is2D, s_params_orig) 
    2137  
    2138             # TODO: merge rest of beta approx implementation in 
    2139             # These parameters are not part of P(Q) nor S(Q), but are added only to the product model (e.g. specifying 
    2140             # structure factor calculation mode) 
    2141             # product_params = all_params[p_pars_len+s_pars_len:] 
    2142  
    21432125        # Add heading row 
    21442126        FittingUtilities.addHeadingRowToModel(self._model_model, structure_factor) 
    21452127 
    2146         # Update QModel 
    2147         for row in new_rows: 
    2148             self._model_model.appendRow(row) 
    2149             # disable fitting of parameters not listed in self.kernel_module (probably radius_effective) 
    2150             # if row[0].text() not in self.kernel_module.params.keys(): 
    2151             #     row_num = self._model_model.rowCount() - 1 
    2152             #     FittingUtilities.markParameterDisabled(self._model_model, row_num) 
     2128        # Get new rows for QModel 
     2129        # Any renamed parameters are stored as data in the relevant item, for later handling 
     2130        FittingUtilities.addSimpleParametersToModel( 
     2131                s_params, 
     2132                self.is2D, 
     2133                s_params_orig, 
     2134                self._model_model, 
     2135                self.lstParams) 
    21532136 
    21542137    def haveParamsToFit(self): 
     
    28132796            self._model_model.removeRows(first_row, remove_rows) 
    28142797 
    2815         new_rows = FittingUtilities.addShellsToModel(self.model_parameters, self._model_model, index, first_row) 
     2798        new_rows = FittingUtilities.addShellsToModel( 
     2799                self.model_parameters, 
     2800                self._model_model, 
     2801                index, 
     2802                first_row, 
     2803                self.lstParams) 
     2804 
    28162805        self._num_shell_params = len(new_rows) 
    2817  
    28182806        self.current_shell_displayed = index 
    28192807 
  • src/sas/qtgui/Plotting/Plotter.py

    rb764ae5 rc2f3ca2  
    3030        # Dictionary of {plot_id:Data1d} 
    3131        self.plot_dict = {} 
    32  
     32        # Dictionaty of {plot_id:line} 
     33 
     34        self.plot_lines = {} 
    3335        # Window for text add 
    3436        self.addText = AddText(self) 
     
    182184        self.plot_dict[self._data.id] = self.data 
    183185 
     186        self.plot_lines[self._data.id] = line 
     187 
    184188        # Now add the legend with some customizations. 
    185189 
     
    196200 
    197201        # refresh canvas 
    198         self.canvas.draw_idle() 
     202        self.canvas.draw() 
    199203        # This is an important processEvent. 
    200204        # This allows charts to be properly updated in order 
     
    416420        This effectlvely refreshes the chart with changes to one of its plots 
    417421        """ 
     422        import logging 
    418423        self.removePlot(id) 
    419424        self.plot(data=new_plot) 
     
    470475        """ 
    471476        selected_plot = self.plot_dict[id] 
    472  
     477        selected_line = self.plot_lines[id] 
    473478        # Old style color - single integer for enum color 
    474479        # New style color - #hhhhhh 
Note: See TracChangeset for help on using the changeset viewer.