Changes in / [fb560d2:b69b549] in sasview


Ignore:
Location:
src/sas/qtgui/Perspectives/Fitting
Files:
1 added
2 edited

Legend:

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

    r70f4458 r70f4458  
    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

    r0109f2a r0109f2a  
    20792079        self.shell_names = self.shellNamesList() 
    20802080 
    2081         # Get new rows for QModel 
    2082         new_rows = FittingUtilities.addParametersToModel(self.model_parameters, self.kernel_module, self.is2D) 
    2083  
    20842081        # Add heading row 
    20852082        FittingUtilities.addHeadingRowToModel(self._model_model, model_name) 
    20862083 
    2087         # Update QModel 
    2088         for row in new_rows: 
    2089             self._model_model.appendRow(row) 
     2084        # Update the QModel 
     2085        FittingUtilities.addParametersToModel( 
     2086                self.model_parameters, 
     2087                self.kernel_module, 
     2088                self.is2D, 
     2089                self._model_model, 
     2090                self.lstParams) 
    20902091 
    20912092    def fromStructureFactorToQModel(self, structure_factor): 
     
    20992100        p_kernel = self.kernel_module 
    21002101 
    2101         if p_kernel is None: 
    2102             # Not a product model, just S(Q) 
    2103             self.kernel_module = s_kernel 
    2104             params = modelinfo.ParameterTable(self.kernel_module._model_info.parameters.kernel_parameters) 
    2105             new_rows = FittingUtilities.addSimpleParametersToModel(params, self.is2D) 
     2102        # if p_kernel is None: 
     2103        #     # Not a product model, just S(Q) 
     2104        #     self.kernel_module = s_kernel 
     2105        #     params = modelinfo.ParameterTable(self.kernel_module._model_info.parameters.kernel_parameters) 
     2106        #     FittingUtilities.addSimpleParametersToModel(params, self.is2D) 
     2107        # else: 
     2108        p_pars_len = len(p_kernel._model_info.parameters.kernel_parameters) 
     2109        s_pars_len = len(s_kernel._model_info.parameters.kernel_parameters) 
     2110 
     2111        self.kernel_module = MultiplicationModel(p_kernel, s_kernel) 
     2112        all_params = self.kernel_module._model_info.parameters.kernel_parameters 
     2113        all_param_names = [param.name for param in all_params] 
     2114 
     2115        # S(Q) params from the product model are not necessarily the same as those from the S(Q) model; any 
     2116        # conflicting names with P(Q) params will cause a rename 
     2117 
     2118        if "radius_effective_mode" in all_param_names: 
     2119            # Show all parameters 
     2120            s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len]) 
     2121            s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters) 
    21062122        else: 
    2107             p_pars_len = len(p_kernel._model_info.parameters.kernel_parameters) 
    2108             s_pars_len = len(s_kernel._model_info.parameters.kernel_parameters) 
    2109  
    2110             self.kernel_module = MultiplicationModel(p_kernel, s_kernel) 
    2111             all_params = self.kernel_module._model_info.parameters.kernel_parameters 
    2112             all_param_names = [param.name for param in all_params] 
    2113  
    2114             # S(Q) params from the product model are not necessarily the same as those from the S(Q) model; any 
    2115             # conflicting names with P(Q) params will cause a rename; we also lose radius_effective (for now...) 
    2116  
    2117             # TODO: merge rest of beta approx implementation in 
    2118             # This is to ensure compatibility when we merge beta approx support in...! 
    2119  
    2120             # radius_effective is always s_params[0] 
    2121  
    2122             # if radius_effective_mode is in all_params, then all_params contains radius_effective and we want to 
    2123             # keep it in the model 
    2124  
    2125             # if radius_effective_mode is NOT in all_params, then radius_effective should NOT be kept, because the user 
    2126             # cannot specify it themselves; but, make sure we only remove it if it's actually there in the first place 
    2127             # (sasmodels master removes it already) 
    2128             if "radius_effective_mode" in all_param_names: 
    2129                 # Show all parameters 
    2130                 s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len]) 
    2131                 s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters) 
     2123            # Ensure radius_effective is not displayed 
     2124            s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters[1:]) 
     2125            if "radius_effective" in all_param_names: 
     2126                s_params = modelinfo.ParameterTable(all_params[p_pars_len+1:p_pars_len+s_pars_len]) 
    21322127            else: 
    2133                 # Ensure radius_effective is not displayed 
    2134                 s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters[1:]) 
    2135                 if "radius_effective" in all_param_names: 
    2136                     s_params = modelinfo.ParameterTable(all_params[p_pars_len+1:p_pars_len+s_pars_len]) 
    2137                 else: 
    2138                     s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len-1]) 
    2139  
    2140             # Get new rows for QModel 
    2141             # Any renamed parameters are stored as data in the relevant item, for later handling 
    2142             new_rows = FittingUtilities.addSimpleParametersToModel(s_params, self.is2D, s_params_orig) 
    2143  
    2144             # TODO: merge rest of beta approx implementation in 
    2145             # These parameters are not part of P(Q) nor S(Q), but are added only to the product model (e.g. specifying 
    2146             # structure factor calculation mode) 
    2147             # product_params = all_params[p_pars_len+s_pars_len:] 
     2128                s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len-1]) 
    21482129 
    21492130        # Add heading row 
    21502131        FittingUtilities.addHeadingRowToModel(self._model_model, structure_factor) 
    21512132 
    2152         # Update QModel 
    2153         for row in new_rows: 
    2154             self._model_model.appendRow(row) 
    2155             # disable fitting of parameters not listed in self.kernel_module (probably radius_effective) 
    2156             # if row[0].text() not in self.kernel_module.params.keys(): 
    2157             #     row_num = self._model_model.rowCount() - 1 
    2158             #     FittingUtilities.markParameterDisabled(self._model_model, row_num) 
     2133        # Get new rows for QModel 
     2134        # Any renamed parameters are stored as data in the relevant item, for later handling 
     2135        FittingUtilities.addSimpleParametersToModel( 
     2136                s_params, 
     2137                self.is2D, 
     2138                s_params_orig, 
     2139                self._model_model, 
     2140                self.lstParams) 
    21592141 
    21602142    def haveParamsToFit(self): 
     
    28192801            self._model_model.removeRows(first_row, remove_rows) 
    28202802 
    2821         new_rows = FittingUtilities.addShellsToModel(self.model_parameters, self._model_model, index, first_row) 
     2803        new_rows = FittingUtilities.addShellsToModel( 
     2804                self.model_parameters, 
     2805                self._model_model, 
     2806                index, 
     2807                first_row, 
     2808                self.lstParams) 
     2809 
    28222810        self._num_shell_params = len(new_rows) 
    2823  
    28242811        self.current_shell_displayed = index 
    28252812 
Note: See TracChangeset for help on using the changeset viewer.