Changeset 01b4877 in sasview for src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
- Timestamp:
- Sep 7, 2018 10:53:02 AM (6 years ago)
- 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:
- c0de493
- Parents:
- 8136e09 (diff), f0365a2e (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
r8136e09 r01b4877 91 91 fittingFinishedSignal = QtCore.pyqtSignal(tuple) 92 92 batchFittingFinishedSignal = QtCore.pyqtSignal(tuple) 93 Calc1DFinishedSignal = QtCore.pyqtSignal( tuple)94 Calc2DFinishedSignal = QtCore.pyqtSignal( tuple)93 Calc1DFinishedSignal = QtCore.pyqtSignal(dict) 94 Calc2DFinishedSignal = QtCore.pyqtSignal(dict) 95 95 96 96 def __init__(self, parent=None, data=None, tab_id=1): … … 219 219 # Utility variable to enable unselectable option in category combobox 220 220 self._previous_category_index = 0 221 # Utility variable for multishell display 222 self._last_model_row = 0 221 # Utility variables for multishell display 222 self._n_shells_row = 0 223 self._num_shell_params = 0 223 224 # Dictionary of {model name: model class} for the current category 224 225 self.models = {} … … 676 677 Return list of all parameters for the current model 677 678 """ 678 return [self._model_model.item(row).text() for row in range(self._model_model.rowCount())] 679 return [self._model_model.item(row).text() 680 for row in range(self._model_model.rowCount()) 681 if self.isCheckable(row)] 679 682 680 683 def modifyViewOnRow(self, row, font=None, brush=None): … … 704 707 assert isinstance(constraint, Constraint) 705 708 assert 0 <= row <= self._model_model.rowCount() 709 assert self.isCheckable(row) 706 710 707 711 item = QtGui.QStandardItem() … … 724 728 max_col = self.lstParams.itemDelegate().param_max 725 729 for row in self.selectedParameters(): 730 assert(self.isCheckable(row)) 726 731 param = self._model_model.item(row, 0).text() 727 732 value = self._model_model.item(row, 1).text() … … 766 771 max_col = self.lstParams.itemDelegate().param_max 767 772 for row in range(self._model_model.rowCount()): 773 if not self.isCheckable(row): 774 continue 768 775 if not self.rowHasConstraint(row): 769 776 continue … … 794 801 For the given row, return its constraint, if any 795 802 """ 796 try:803 if self.isCheckable(row): 797 804 item = self._model_model.item(row, 1) 798 return item.child(0).data() 799 except AttributeError: 800 # return none when no constraints 801 return None 805 try: 806 return item.child(0).data() 807 except AttributeError: 808 # return none when no constraints 809 pass 810 return None 802 811 803 812 def rowHasConstraint(self, row): … … 805 814 Finds out if row of the main model has a constraint child 806 815 """ 807 item = self._model_model.item(row, 1) 808 if item.hasChildren(): 809 c = item.child(0).data() 810 if isinstance(c, Constraint): 811 return True 816 if self.isCheckable(row): 817 item = self._model_model.item(row, 1) 818 if item.hasChildren(): 819 c = item.child(0).data() 820 if isinstance(c, Constraint): 821 return True 812 822 return False 813 823 … … 816 826 Finds out if row of the main model has an active constraint child 817 827 """ 818 item = self._model_model.item(row, 1) 819 if item.hasChildren(): 820 c = item.child(0).data() 821 if isinstance(c, Constraint) and c.active: 822 return True 828 if self.isCheckable(row): 829 item = self._model_model.item(row, 1) 830 if item.hasChildren(): 831 c = item.child(0).data() 832 if isinstance(c, Constraint) and c.active: 833 return True 823 834 return False 824 835 … … 827 838 Finds out if row of the main model has an active, nontrivial constraint child 828 839 """ 829 item = self._model_model.item(row, 1) 830 if item.hasChildren(): 831 c = item.child(0).data() 832 if isinstance(c, Constraint) and c.func and c.active: 833 return True 840 if self.isCheckable(row): 841 item = self._model_model.item(row, 1) 842 if item.hasChildren(): 843 c = item.child(0).data() 844 if isinstance(c, Constraint) and c.func and c.active: 845 return True 834 846 return False 835 847 … … 1495 1507 # update charts 1496 1508 self.onPlot() 1509 #self.recalculatePlotData() 1510 1497 1511 1498 1512 # Read only value - we can get away by just printing it here … … 1577 1591 # internal so can use closure for param_dict 1578 1592 param_name = str(self._model_model.item(row, 0).text()) 1579 if param_name not in list(param_dict.keys()):1593 if not self.isCheckable(row) or param_name not in list(param_dict.keys()): 1580 1594 return 1581 1595 # modify the param value 1582 1596 param_repr = GuiUtils.formatNumber(param_dict[param_name][0], high=True) 1583 1597 self._model_model.item(row, 1).setText(param_repr) 1598 self.kernel_module.setParam(param_name, param_dict[param_name][0]) 1584 1599 if self.has_error_column: 1585 1600 error_repr = GuiUtils.formatNumber(param_dict[param_name][1], high=True) … … 1589 1604 # Utility function for updateof polydispersity part of the main model 1590 1605 param_name = str(self._model_model.item(row, 0).text())+'.width' 1591 if param_name not in list(param_dict.keys()):1606 if not self.isCheckable(row) or param_name not in list(param_dict.keys()): 1592 1607 return 1593 1608 # modify the param value … … 1623 1638 poly_item.insertColumn(2, [QtGui.QStandardItem("")]) 1624 1639 1625 # block signals temporarily, so we don't end up1626 # updating charts with every single model change on the end of fitting1627 self._model_model.blockSignals(True)1628 1629 1640 if not self.has_error_column: 1630 1641 # create top-level error column … … 1633 1644 self.iterateOverModel(createErrorColumn) 1634 1645 1635 # we need to enable signals for this, otherwise the final column mysteriously disappears (don't ask, I don't1636 # know)1637 self._model_model.blockSignals(False)1638 1646 self._model_model.insertColumn(2, error_column) 1639 self._model_model.blockSignals(True)1640 1647 1641 1648 FittingUtilities.addErrorHeadersToModel(self._model_model) … … 1646 1653 self.has_error_column = True 1647 1654 1655 # block signals temporarily, so we don't end up 1656 # updating charts with every single model change on the end of fitting 1657 self._model_model.itemChanged.disconnect() 1648 1658 self.iterateOverModel(updateFittedValues) 1649 1659 self.iterateOverModel(updatePolyValues) 1650 1651 self._model_model.blockSignals(False) 1660 self._model_model.itemChanged.connect(self.onMainParamsChange) 1652 1661 1653 1662 # Adjust the table cells width. … … 1684 1693 param_repr = GuiUtils.formatNumber(param_dict[param_name][0], high=True) 1685 1694 self._poly_model.item(row_i, 1).setText(param_repr) 1695 self.kernel_module.setParam(param_name, param_dict[param_name][0]) 1686 1696 if self.has_poly_error_column: 1687 1697 error_repr = GuiUtils.formatNumber(param_dict[param_name][1], high=True) 1688 1698 self._poly_model.item(row_i, 2).setText(error_repr) 1689 1690 1699 1691 1700 def createErrorColumn(row_i): … … 1708 1717 # block signals temporarily, so we don't end up 1709 1718 # updating charts with every single model change on the end of fitting 1710 self._poly_model. blockSignals(True)1719 self._poly_model.itemChanged.disconnect() 1711 1720 self.iterateOverPolyModel(updateFittedValues) 1712 self._poly_model. blockSignals(False)1721 self._poly_model.itemChanged.connect(self.onPolyModelChange) 1713 1722 1714 1723 if self.has_poly_error_column: … … 1720 1729 1721 1730 # switch off reponse to model change 1722 self._poly_model.blockSignals(True)1723 1731 self._poly_model.insertColumn(2, error_column) 1724 self._poly_model.blockSignals(False)1725 1732 FittingUtilities.addErrorPolyHeadersToModel(self._poly_model) 1726 1733 … … 1755 1762 param_repr = GuiUtils.formatNumber(param_dict[param_name][0], high=True) 1756 1763 self._magnet_model.item(row, 1).setText(param_repr) 1764 self.kernel_module.setParam(param_name, param_dict[param_name][0]) 1757 1765 if self.has_magnet_error_column: 1758 1766 error_repr = GuiUtils.formatNumber(param_dict[param_name][1], high=True) … … 1774 1782 # block signals temporarily, so we don't end up 1775 1783 # updating charts with every single model change on the end of fitting 1776 self._magnet_model. blockSignals(True)1784 self._magnet_model.itemChanged.disconnect() 1777 1785 self.iterateOverMagnetModel(updateFittedValues) 1778 self._magnet_model. blockSignals(False)1786 self._magnet_model.itemChanged.connect(self.onMagnetModelChange) 1779 1787 1780 1788 if self.has_magnet_error_column: … … 1786 1794 1787 1795 # switch off reponse to model change 1788 self._magnet_model.blockSignals(True)1789 1796 self._magnet_model.insertColumn(2, error_column) 1790 self._magnet_model.blockSignals(False)1791 1797 FittingUtilities.addErrorHeadersToModel(self._magnet_model) 1792 1798 … … 1800 1806 self.cmdPlot.setText("Show Plot") 1801 1807 # Force data recalculation so existing charts are updated 1808 self.showPlot() 1802 1809 self.recalculatePlotData() 1803 self.showPlot()1804 1810 1805 1811 def onSmearingOptionsUpdate(self): … … 1966 1972 # Crete/overwrite model items 1967 1973 self._model_model.clear() 1968 1969 # First, add parameters from the main model 1970 if model_name is not None: 1974 self._poly_model.clear() 1975 self._magnet_model.clear() 1976 1977 if model_name is None: 1978 if structure_factor not in (None, "None"): 1979 # S(Q) on its own, treat the same as a form factor 1980 self.kernel_module = None 1981 self.fromStructureFactorToQModel(structure_factor) 1982 else: 1983 # No models selected 1984 return 1985 else: 1971 1986 self.fromModelToQModel(model_name) 1972 1973 # Then, add structure factor derived parameters 1974 if structure_factor is not None and structure_factor != "None": 1975 if model_name is None: 1976 # Instantiate the current sasmodel for SF-only models 1977 self.kernel_module = self.models[structure_factor]() 1978 self.fromStructureFactorToQModel(structure_factor) 1979 else: 1987 self.addExtraShells() 1988 1980 1989 # Allow the SF combobox visibility for the given sasmodel 1981 1990 self.enableStructureFactorControl(structure_factor) 1991 1992 # Add S(Q) 1982 1993 if self.cbStructureFactor.isEnabled(): 1983 1994 structure_factor = self.cbStructureFactor.currentText() 1984 1995 self.fromStructureFactorToQModel(structure_factor) 1985 1996 1986 # Then, add multishells 1987 if model_name is not None: 1988 # Multishell models need additional treatment 1989 self.addExtraShells() 1990 1991 # Add polydispersity to the model 1992 self.poly_params = {} 1993 self.setPolyModel() 1994 # Add magnetic parameters to the model 1995 self.magnet_params = {} 1996 self.setMagneticModel() 1997 # Add polydispersity to the model 1998 self.poly_params = {} 1999 self.setPolyModel() 2000 # Add magnetic parameters to the model 2001 self.magnet_params = {} 2002 self.setMagneticModel() 1997 2003 1998 2004 # Adjust the table cells width … … 2067 2073 self.shell_names = self.shellNamesList() 2068 2074 2075 # Add heading row 2076 FittingUtilities.addHeadingRowToModel(self._model_model, model_name) 2077 2069 2078 # Update the QModel 2070 new_rows = FittingUtilities.addParametersToModel(self.model_parameters, self.kernel_module, self.is2D)2071 2072 for row in new_rows:2073 self._model_model.appendRow(row)2074 # Update the counter used for multishell display2075 self._last_model_row = self._model_model.rowCount()2079 FittingUtilities.addParametersToModel( 2080 self.model_parameters, 2081 self.kernel_module, 2082 self.is2D, 2083 self._model_model, 2084 self.lstParams) 2076 2085 2077 2086 def fromStructureFactorToQModel(self, structure_factor): … … 2081 2090 if structure_factor is None or structure_factor=="None": 2082 2091 return 2083 structure_module = generate.load_kernel_module(structure_factor) 2084 structure_parameters = modelinfo.make_parameter_table(getattr(structure_module, 'parameters', [])) 2085 2086 structure_kernel = self.models[structure_factor]() 2087 form_kernel = self.kernel_module 2088 2089 self.kernel_module = MultiplicationModel(form_kernel, structure_kernel) 2090 2091 new_rows = FittingUtilities.addSimpleParametersToModel(structure_parameters, self.is2D) 2092 for row in new_rows: 2093 self._model_model.appendRow(row) 2094 # disable fitting of parameters not listed in self.kernel_module (probably radius_effective) 2095 if row[0].text() not in self.kernel_module.params.keys(): 2096 row_num = self._model_model.rowCount() - 1 2097 FittingUtilities.markParameterDisabled(self._model_model, row_num) 2098 2099 # grab list of params injected by sasmodels.product 2100 # (only supporting sasmodels master until ESS_GUI merge!!!) 2101 num_p_params = len(form_kernel._model_info.parameters.kernel_parameters) 2102 num_s_params = len(structure_kernel._model_info.parameters.kernel_parameters) 2103 product_params = modelinfo.ParameterTable( 2104 self.kernel_module._model_info.parameters.kernel_parameters[num_p_params+num_s_params-1:]) 2105 product_rows = FittingUtilities.addSimpleParametersToModel(product_params, self.is2D) 2106 2107 # product params should go at the top of the list, below scale & background 2108 row_num = 2 2109 for row in product_rows: 2110 self._model_model.insertRow(row_num, row) 2111 row_num += 1 2112 2113 # Update the counter used for multishell display 2114 self._last_model_row = self._model_model.rowCount() 2092 2093 product_params = None 2094 2095 if self.kernel_module is None: 2096 # Structure factor is the only selected model; build it and show all its params 2097 self.kernel_module = self.models[structure_factor]() 2098 s_params = self.kernel_module._model_info.parameters 2099 s_params_orig = s_params 2100 else: 2101 s_kernel = self.models[structure_factor]() 2102 p_kernel = self.kernel_module 2103 2104 p_pars_len = len(p_kernel._model_info.parameters.kernel_parameters) 2105 s_pars_len = len(s_kernel._model_info.parameters.kernel_parameters) 2106 2107 self.kernel_module = MultiplicationModel(p_kernel, s_kernel) 2108 all_params = self.kernel_module._model_info.parameters.kernel_parameters 2109 all_param_names = [param.name for param in all_params] 2110 2111 # S(Q) params from the product model are not necessarily the same as those from the S(Q) model; any 2112 # conflicting names with P(Q) params will cause a rename 2113 2114 if "radius_effective_mode" in all_param_names: 2115 # Show all parameters 2116 # In this case, radius_effective is NOT pruned by sasmodels.product 2117 s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len]) 2118 s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters) 2119 product_params = modelinfo.ParameterTable( 2120 self.kernel_module._model_info.parameters.kernel_parameters[p_pars_len+s_pars_len:]) 2121 else: 2122 # Ensure radius_effective is not displayed 2123 s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters[1:]) 2124 if "radius_effective" in all_param_names: 2125 # In this case, radius_effective is NOT pruned by sasmodels.product 2126 s_params = modelinfo.ParameterTable(all_params[p_pars_len+1:p_pars_len+s_pars_len]) 2127 product_params = modelinfo.ParameterTable( 2128 self.kernel_module._model_info.parameters.kernel_parameters[p_pars_len+s_pars_len:]) 2129 else: 2130 # In this case, radius_effective is pruned by sasmodels.product 2131 s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len-1]) 2132 product_params = modelinfo.ParameterTable( 2133 self.kernel_module._model_info.parameters.kernel_parameters[p_pars_len+s_pars_len-1:]) 2134 2135 # Add heading row 2136 FittingUtilities.addHeadingRowToModel(self._model_model, structure_factor) 2137 2138 # Get new rows for QModel 2139 # Any renamed parameters are stored as data in the relevant item, for later handling 2140 FittingUtilities.addSimpleParametersToModel( 2141 parameters=s_params, 2142 is2D=self.is2D, 2143 parameters_original=s_params_orig, 2144 model=self._model_model, 2145 view=self.lstParams) 2146 2147 # Insert product-only params into QModel 2148 if product_params: 2149 prod_rows = FittingUtilities.addSimpleParametersToModel( 2150 parameters=product_params, 2151 is2D=self.is2D, 2152 parameters_original=None, 2153 model=self._model_model, 2154 view=self.lstParams, 2155 row_num=2) 2156 2157 # Since this all happens after shells are dealt with and we've inserted rows, fix this counter 2158 self._n_shells_row += len(prod_rows) 2115 2159 2116 2160 def haveParamsToFit(self): … … 2138 2182 model_row = item.row() 2139 2183 name_index = self._model_model.index(model_row, 0) 2184 name_item = self._model_model.itemFromIndex(name_index) 2140 2185 2141 2186 # Extract changed value. … … 2146 2191 return 2147 2192 2148 parameter_name = str(self._model_model.data(name_index)) # sld, background etc. 2193 # if the item has user data, this is the actual parameter name (e.g. to handle duplicate names) 2194 if name_item.data(QtCore.Qt.UserRole): 2195 parameter_name = str(name_item.data(QtCore.Qt.UserRole)) 2196 else: 2197 parameter_name = str(self._model_model.data(name_index)) 2149 2198 2150 2199 # Update the parameter value - note: this supports +/-inf as well … … 2380 2429 new_plots.append(sq_data) 2381 2430 2382 # Update/generate plots2383 2431 for plot in new_plots: 2384 2432 self.communicate.plotUpdateSignal.emit([plot]) … … 2580 2628 def updateFunctionCaption(row): 2581 2629 # Utility function for update of polydispersity function name in the main model 2630 if not self.isCheckable(row): 2631 return 2582 2632 self._model_model.blockSignals(True) 2583 2633 param_name = str(self._model_model.item(row, 0).text()) … … 2752 2802 2753 2803 self.lstParams.setIndexWidget(shell_index, func) 2754 self._ last_model_row = self._model_model.rowCount()2804 self._n_shells_row = shell_row - 1 2755 2805 2756 2806 # Set the index to the state-kept value … … 2763 2813 """ 2764 2814 # Find row location of the combobox 2765 last_row = self._last_model_row2766 remove_rows = self._ model_model.rowCount() - last_row2815 first_row = self._n_shells_row + 1 2816 remove_rows = self._num_shell_params 2767 2817 2768 2818 if remove_rows > 1: 2769 self._model_model.removeRows(last_row, remove_rows) 2770 2771 FittingUtilities.addShellsToModel(self.model_parameters, self._model_model, index) 2819 self._model_model.removeRows(first_row, remove_rows) 2820 2821 new_rows = FittingUtilities.addShellsToModel( 2822 self.model_parameters, 2823 self._model_model, 2824 index, 2825 first_row, 2826 self.lstParams) 2827 2828 self._num_shell_params = len(new_rows) 2772 2829 self.current_shell_displayed = index 2773 2830
Note: See TracChangeset
for help on using the changeset viewer.