Changes in src/sas/qtgui/Perspectives/Fitting/FittingWidget.py [f84d793:d4ba565] in sasview
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
rf84d793 rd4ba565 48 48 from sas.qtgui.Perspectives.Fitting.ReportPageLogic import ReportPageLogic 49 49 50 51 50 TAB_MAGNETISM = 4 52 51 TAB_POLY = 3 … … 91 90 fittingFinishedSignal = QtCore.pyqtSignal(tuple) 92 91 batchFittingFinishedSignal = QtCore.pyqtSignal(tuple) 93 Calc1DFinishedSignal = QtCore.pyqtSignal( tuple)94 Calc2DFinishedSignal = QtCore.pyqtSignal( tuple)92 Calc1DFinishedSignal = QtCore.pyqtSignal(dict) 93 Calc2DFinishedSignal = QtCore.pyqtSignal(dict) 95 94 96 95 def __init__(self, parent=None, data=None, tab_id=1): … … 188 187 189 188 # Overwrite data type descriptor 189 190 190 self.is2D = True if isinstance(self.logic.data, Data2D) else False 191 191 … … 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 = {} … … 247 248 # copy of current kernel model 248 249 self.kernel_module_copy = None 250 251 # dictionaries of current params 252 self.poly_params = {} 253 self.magnet_params = {} 249 254 250 255 # Page id for fitting … … 558 563 When clicked on white space: model description 559 564 """ 560 rows = [s.row() for s in self.lstParams.selectionModel().selectedRows()] 565 rows = [s.row() for s in self.lstParams.selectionModel().selectedRows() 566 if self.isCheckable(s.row())] 561 567 menu = self.showModelDescription() if not rows else self.modelContextMenu(rows) 562 568 try: … … 672 678 Return list of all parameters for the current model 673 679 """ 674 return [self._model_model.item(row).text() for row in range(self._model_model.rowCount())] 680 return [self._model_model.item(row).text() 681 for row in range(self._model_model.rowCount()) 682 if self.isCheckable(row)] 675 683 676 684 def modifyViewOnRow(self, row, font=None, brush=None): … … 700 708 assert isinstance(constraint, Constraint) 701 709 assert 0 <= row <= self._model_model.rowCount() 710 assert self.isCheckable(row) 702 711 703 712 item = QtGui.QStandardItem() … … 720 729 max_col = self.lstParams.itemDelegate().param_max 721 730 for row in self.selectedParameters(): 731 assert(self.isCheckable(row)) 722 732 param = self._model_model.item(row, 0).text() 723 733 value = self._model_model.item(row, 1).text() … … 762 772 max_col = self.lstParams.itemDelegate().param_max 763 773 for row in range(self._model_model.rowCount()): 774 if not self.isCheckable(row): 775 continue 764 776 if not self.rowHasConstraint(row): 765 777 continue … … 788 800 def getConstraintForRow(self, row): 789 801 """ 790 For the given row, return its constraint, if any 791 """ 802 For the given row, return its constraint, if any (otherwise None) 803 """ 804 if not self.isCheckable(row): 805 return None 806 item = self._model_model.item(row, 1) 792 807 try: 793 item = self._model_model.item(row, 1)794 808 return item.child(0).data() 795 809 except AttributeError: 796 # return none when no constraints797 810 return None 798 811 … … 801 814 Finds out if row of the main model has a constraint child 802 815 """ 816 if not self.isCheckable(row): 817 return False 803 818 item = self._model_model.item(row, 1) 804 if item.hasChildren(): 805 c = item.child(0).data() 806 if isinstance(c, Constraint): 807 return True 819 if not item.hasChildren(): 820 return False 821 c = item.child(0).data() 822 if isinstance(c, Constraint): 823 return True 808 824 return False 809 825 … … 812 828 Finds out if row of the main model has an active constraint child 813 829 """ 830 if not self.isCheckable(row): 831 return False 814 832 item = self._model_model.item(row, 1) 815 if item.hasChildren(): 816 c = item.child(0).data() 817 if isinstance(c, Constraint) and c.active: 818 return True 833 if not item.hasChildren(): 834 return False 835 c = item.child(0).data() 836 if isinstance(c, Constraint) and c.active: 837 return True 819 838 return False 820 839 … … 823 842 Finds out if row of the main model has an active, nontrivial constraint child 824 843 """ 844 if not self.isCheckable(row): 845 return False 825 846 item = self._model_model.item(row, 1) 826 if item.hasChildren(): 827 c = item.child(0).data() 828 if isinstance(c, Constraint) and c.func and c.active: 829 return True 847 if not item.hasChildren(): 848 return False 849 c = item.child(0).data() 850 if isinstance(c, Constraint) and c.func and c.active: 851 return True 830 852 return False 831 853 … … 1037 1059 # Show constraint, if present 1038 1060 row = rows[0].row() 1039 if self.rowHasConstraint(row): 1040 func = self.getConstraintForRow(row).func 1041 if func is not None: 1042 self.communicate.statusBarUpdateSignal.emit("Active constrain: "+func) 1061 if not self.rowHasConstraint(row): 1062 return 1063 func = self.getConstraintForRow(row).func 1064 if func is not None: 1065 self.communicate.statusBarUpdateSignal.emit("Active constrain: "+func) 1043 1066 1044 1067 def replaceConstraintName(self, old_name, new_name=""): … … 1186 1209 # Update the sasmodel 1187 1210 # PD[ratio] -> width, npts -> npts, nsigs -> nsigmas 1188 self.kernel_module.setParam(parameter_name + '.' + delegate.columnDict()[model_column], value) 1211 #self.kernel_module.setParam(parameter_name + '.' + delegate.columnDict()[model_column], value) 1212 key = parameter_name + '.' + delegate.columnDict()[model_column] 1213 self.poly_params[key] = value 1189 1214 1190 1215 # Update plot … … 1195 1220 row = self.getRowFromName(parameter_name) 1196 1221 param_item = self._model_model.item(row) 1222 self._model_model.blockSignals(True) 1197 1223 param_item.child(0).child(0, model_column).setText(item.text()) 1224 self._model_model.blockSignals(False) 1198 1225 1199 1226 def onMagnetModelChange(self, item): … … 1224 1251 # Unparsable field 1225 1252 return 1226 1227 property_index = self._magnet_model.headerData(1, model_column)-1 # Value, min, max, etc. 1228 1229 # Update the parameter value - note: this supports +/-inf as well 1230 self.kernel_module.params[parameter_name] = value 1231 1232 # min/max to be changed in self.kernel_module.details[parameter_name] = ['Ang', 0.0, inf] 1233 self.kernel_module.details[parameter_name][property_index] = value 1234 1235 # Force the chart update when actual parameters changed 1236 if model_column == 1: 1253 delegate = self.lstMagnetic.itemDelegate() 1254 1255 if model_column > 1: 1256 if model_column == delegate.mag_min: 1257 pos = 1 1258 elif model_column == delegate.mag_max: 1259 pos = 2 1260 elif model_column == delegate.mag_unit: 1261 pos = 0 1262 else: 1263 raise AttributeError("Wrong column in magnetism table.") 1264 # min/max to be changed in self.kernel_module.details[parameter_name] = ['Ang', 0.0, inf] 1265 self.kernel_module.details[parameter_name][pos] = value 1266 else: 1267 self.magnet_params[parameter_name] = value 1268 #self.kernel_module.setParam(parameter_name) = value 1269 # Force the chart update when actual parameters changed 1237 1270 self.recalculatePlotData() 1238 1271 … … 1481 1514 # update charts 1482 1515 self.onPlot() 1516 #self.recalculatePlotData() 1517 1483 1518 1484 1519 # Read only value - we can get away by just printing it here … … 1495 1530 # Data going in 1496 1531 data = self.logic.data 1497 model = self.kernel_module1532 model = copy.deepcopy(self.kernel_module) 1498 1533 qmin = self.q_range_min 1499 1534 qmax = self.q_range_max 1535 # add polydisperse/magnet parameters if asked 1536 self.updateKernelModelWithExtraParams(model) 1500 1537 1501 1538 params_to_fit = self.main_params_to_fit … … 1561 1598 # internal so can use closure for param_dict 1562 1599 param_name = str(self._model_model.item(row, 0).text()) 1563 if param_name not in list(param_dict.keys()):1600 if not self.isCheckable(row) or param_name not in list(param_dict.keys()): 1564 1601 return 1565 1602 # modify the param value 1566 1603 param_repr = GuiUtils.formatNumber(param_dict[param_name][0], high=True) 1567 1604 self._model_model.item(row, 1).setText(param_repr) 1605 self.kernel_module.setParam(param_name, param_dict[param_name][0]) 1568 1606 if self.has_error_column: 1569 1607 error_repr = GuiUtils.formatNumber(param_dict[param_name][1], high=True) … … 1573 1611 # Utility function for updateof polydispersity part of the main model 1574 1612 param_name = str(self._model_model.item(row, 0).text())+'.width' 1575 if param_name not in list(param_dict.keys()):1613 if not self.isCheckable(row) or param_name not in list(param_dict.keys()): 1576 1614 return 1577 1615 # modify the param value … … 1607 1645 poly_item.insertColumn(2, [QtGui.QStandardItem("")]) 1608 1646 1609 # block signals temporarily, so we don't end up1610 # updating charts with every single model change on the end of fitting1611 self._model_model.blockSignals(True)1612 1613 1647 if not self.has_error_column: 1614 1648 # create top-level error column … … 1617 1651 self.iterateOverModel(createErrorColumn) 1618 1652 1619 # we need to enable signals for this, otherwise the final column mysteriously disappears (don't ask, I don't1620 # know)1621 self._model_model.blockSignals(False)1622 1653 self._model_model.insertColumn(2, error_column) 1623 self._model_model.blockSignals(True)1624 1654 1625 1655 FittingUtilities.addErrorHeadersToModel(self._model_model) … … 1630 1660 self.has_error_column = True 1631 1661 1662 # block signals temporarily, so we don't end up 1663 # updating charts with every single model change on the end of fitting 1664 self._model_model.itemChanged.disconnect() 1632 1665 self.iterateOverModel(updateFittedValues) 1633 1666 self.iterateOverModel(updatePolyValues) 1634 1635 self._model_model.blockSignals(False) 1667 self._model_model.itemChanged.connect(self.onMainParamsChange) 1636 1668 1637 1669 # Adjust the table cells width. … … 1668 1700 param_repr = GuiUtils.formatNumber(param_dict[param_name][0], high=True) 1669 1701 self._poly_model.item(row_i, 1).setText(param_repr) 1702 self.kernel_module.setParam(param_name, param_dict[param_name][0]) 1670 1703 if self.has_poly_error_column: 1671 1704 error_repr = GuiUtils.formatNumber(param_dict[param_name][1], high=True) 1672 1705 self._poly_model.item(row_i, 2).setText(error_repr) 1673 1674 1706 1675 1707 def createErrorColumn(row_i): … … 1692 1724 # block signals temporarily, so we don't end up 1693 1725 # updating charts with every single model change on the end of fitting 1694 self._poly_model. blockSignals(True)1726 self._poly_model.itemChanged.disconnect() 1695 1727 self.iterateOverPolyModel(updateFittedValues) 1696 self._poly_model. blockSignals(False)1728 self._poly_model.itemChanged.connect(self.onPolyModelChange) 1697 1729 1698 1730 if self.has_poly_error_column: … … 1704 1736 1705 1737 # switch off reponse to model change 1706 self._poly_model.blockSignals(True)1707 1738 self._poly_model.insertColumn(2, error_column) 1708 self._poly_model.blockSignals(False)1709 1739 FittingUtilities.addErrorPolyHeadersToModel(self._poly_model) 1710 1740 … … 1739 1769 param_repr = GuiUtils.formatNumber(param_dict[param_name][0], high=True) 1740 1770 self._magnet_model.item(row, 1).setText(param_repr) 1771 self.kernel_module.setParam(param_name, param_dict[param_name][0]) 1741 1772 if self.has_magnet_error_column: 1742 1773 error_repr = GuiUtils.formatNumber(param_dict[param_name][1], high=True) … … 1758 1789 # block signals temporarily, so we don't end up 1759 1790 # updating charts with every single model change on the end of fitting 1760 self._magnet_model. blockSignals(True)1791 self._magnet_model.itemChanged.disconnect() 1761 1792 self.iterateOverMagnetModel(updateFittedValues) 1762 self._magnet_model. blockSignals(False)1793 self._magnet_model.itemChanged.connect(self.onMagnetModelChange) 1763 1794 1764 1795 if self.has_magnet_error_column: … … 1770 1801 1771 1802 # switch off reponse to model change 1772 self._magnet_model.blockSignals(True)1773 1803 self._magnet_model.insertColumn(2, error_column) 1774 self._magnet_model.blockSignals(False)1775 1804 FittingUtilities.addErrorHeadersToModel(self._magnet_model) 1776 1805 … … 1784 1813 self.cmdPlot.setText("Show Plot") 1785 1814 # Force data recalculation so existing charts are updated 1815 self.showPlot() 1816 # This is an important processEvent. 1817 # This allows charts to be properly updated in order 1818 # of plots being applied. 1819 QtWidgets.QApplication.processEvents() 1786 1820 self.recalculatePlotData() 1787 self.showPlot()1788 1821 1789 1822 def onSmearingOptionsUpdate(self): … … 1950 1983 # Crete/overwrite model items 1951 1984 self._model_model.clear() 1952 1953 # First, add parameters from the main model 1954 if model_name is not None: 1985 self._poly_model.clear() 1986 self._magnet_model.clear() 1987 1988 if model_name is None: 1989 if structure_factor not in (None, "None"): 1990 # S(Q) on its own, treat the same as a form factor 1991 self.kernel_module = None 1992 self.fromStructureFactorToQModel(structure_factor) 1993 else: 1994 # No models selected 1995 return 1996 else: 1955 1997 self.fromModelToQModel(model_name) 1956 1957 # Then, add structure factor derived parameters 1958 if structure_factor is not None and structure_factor != "None": 1959 if model_name is None: 1960 # Instantiate the current sasmodel for SF-only models 1961 self.kernel_module = self.models[structure_factor]() 1962 self.fromStructureFactorToQModel(structure_factor) 1963 else: 1998 self.addExtraShells() 1999 1964 2000 # Allow the SF combobox visibility for the given sasmodel 1965 2001 self.enableStructureFactorControl(structure_factor) 2002 2003 # Add S(Q) 1966 2004 if self.cbStructureFactor.isEnabled(): 1967 2005 structure_factor = self.cbStructureFactor.currentText() 1968 2006 self.fromStructureFactorToQModel(structure_factor) 1969 2007 1970 # Then, add multishells 1971 if model_name is not None: 1972 # Multishell models need additional treatment 1973 self.addExtraShells() 1974 1975 # Add polydispersity to the model 1976 self.setPolyModel() 1977 # Add magnetic parameters to the model 1978 self.setMagneticModel() 2008 # Add polydispersity to the model 2009 self.poly_params = {} 2010 self.setPolyModel() 2011 # Add magnetic parameters to the model 2012 self.magnet_params = {} 2013 self.setMagneticModel() 1979 2014 1980 2015 # Adjust the table cells width … … 2049 2084 self.shell_names = self.shellNamesList() 2050 2085 2086 # Add heading row 2087 FittingUtilities.addHeadingRowToModel(self._model_model, model_name) 2088 2051 2089 # Update the QModel 2052 new_rows = FittingUtilities.addParametersToModel(self.model_parameters, self.kernel_module, self.is2D)2053 2054 for row in new_rows:2055 self._model_model.appendRow(row)2056 # Update the counter used for multishell display2057 self._last_model_row = self._model_model.rowCount()2090 FittingUtilities.addParametersToModel( 2091 self.model_parameters, 2092 self.kernel_module, 2093 self.is2D, 2094 self._model_model, 2095 self.lstParams) 2058 2096 2059 2097 def fromStructureFactorToQModel(self, structure_factor): … … 2063 2101 if structure_factor is None or structure_factor=="None": 2064 2102 return 2065 structure_module = generate.load_kernel_module(structure_factor) 2066 structure_parameters = modelinfo.make_parameter_table(getattr(structure_module, 'parameters', [])) 2067 2068 structure_kernel = self.models[structure_factor]() 2069 form_kernel = self.kernel_module 2070 2071 self.kernel_module = MultiplicationModel(form_kernel, structure_kernel) 2072 2073 new_rows = FittingUtilities.addSimpleParametersToModel(structure_parameters, self.is2D) 2074 for row in new_rows: 2075 self._model_model.appendRow(row) 2076 # disable fitting of parameters not listed in self.kernel_module (probably radius_effective) 2077 if row[0].text() not in self.kernel_module.params.keys(): 2078 row_num = self._model_model.rowCount() - 1 2079 FittingUtilities.markParameterDisabled(self._model_model, row_num) 2080 2081 # Update the counter used for multishell display 2082 self._last_model_row = self._model_model.rowCount() 2103 2104 if self.kernel_module is None: 2105 # Structure factor is the only selected model; build it and show all its params 2106 self.kernel_module = self.models[structure_factor]() 2107 s_params = self.kernel_module._model_info.parameters 2108 s_params_orig = s_params 2109 2110 else: 2111 s_kernel = self.models[structure_factor]() 2112 p_kernel = self.kernel_module 2113 2114 p_pars_len = len(p_kernel._model_info.parameters.kernel_parameters) 2115 s_pars_len = len(s_kernel._model_info.parameters.kernel_parameters) 2116 2117 self.kernel_module = MultiplicationModel(p_kernel, s_kernel) 2118 all_params = self.kernel_module._model_info.parameters.kernel_parameters 2119 all_param_names = [param.name for param in all_params] 2120 2121 # S(Q) params from the product model are not necessarily the same as those from the S(Q) model; any 2122 # conflicting names with P(Q) params will cause a rename 2123 2124 if "radius_effective_mode" in all_param_names: 2125 # Show all parameters 2126 s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len]) 2127 s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters) 2128 else: 2129 # Ensure radius_effective is not displayed 2130 s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters[1:]) 2131 if "radius_effective" in all_param_names: 2132 s_params = modelinfo.ParameterTable(all_params[p_pars_len+1:p_pars_len+s_pars_len]) 2133 else: 2134 s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len-1]) 2135 2136 # Add heading row 2137 FittingUtilities.addHeadingRowToModel(self._model_model, structure_factor) 2138 2139 # Get new rows for QModel 2140 # Any renamed parameters are stored as data in the relevant item, for later handling 2141 FittingUtilities.addSimpleParametersToModel( 2142 s_params, 2143 self.is2D, 2144 s_params_orig, 2145 self._model_model, 2146 self.lstParams) 2083 2147 2084 2148 def haveParamsToFit(self): … … 2106 2170 model_row = item.row() 2107 2171 name_index = self._model_model.index(model_row, 0) 2172 name_item = self._model_model.itemFromIndex(name_index) 2108 2173 2109 2174 # Extract changed value. … … 2114 2179 return 2115 2180 2116 parameter_name = str(self._model_model.data(name_index)) # sld, background etc. 2181 # if the item has user data, this is the actual parameter name (e.g. to handle duplicate names) 2182 if name_item.data(QtCore.Qt.UserRole): 2183 parameter_name = str(name_item.data(QtCore.Qt.UserRole)) 2184 else: 2185 parameter_name = str(self._model_model.data(name_index)) 2117 2186 2118 2187 # Update the parameter value - note: this supports +/-inf as well … … 2237 2306 return self.completed1D if isinstance(self.data, Data1D) else self.completed2D 2238 2307 2308 def updateKernelModelWithExtraParams(self, model=None): 2309 """ 2310 Updates kernel model 'model' with extra parameters from 2311 the polydisp and magnetism tab, if the tabs are enabled 2312 """ 2313 if model is None: return 2314 if not hasattr(model, 'setParam'): return 2315 2316 # add polydisperse parameters if asked 2317 if self.chkPolydispersity.isChecked(): 2318 for key, value in self.poly_params.items(): 2319 model.setParam(key, value) 2320 # add magnetic params if asked 2321 if self.chkMagnetism.isChecked(): 2322 for key, value in self.magnet_params.items(): 2323 model.setParam(key, value) 2324 2239 2325 def calculateQGridForModelExt(self, data=None, model=None, completefn=None, use_threads=True): 2240 2326 """ … … 2244 2330 data = self.data 2245 2331 if model is None: 2246 model = self.kernel_module 2332 model = copy.deepcopy(self.kernel_module) 2333 self.updateKernelModelWithExtraParams(model) 2334 2247 2335 if completefn is None: 2248 2336 completefn = self.methodCompleteForData() … … 2329 2417 new_plots.append(sq_data) 2330 2418 2419 for plot in new_plots: 2420 self.communicate.plotUpdateSignal.emit([plot]) 2421 2422 def complete2D(self, return_data): 2423 """ 2424 Plot the current 2D data 2425 """ 2426 fitted_data = self.logic.new2DPlot(return_data) 2427 residuals = self.calculateResiduals(fitted_data) 2428 self.model_data = fitted_data 2429 new_plots = [fitted_data] 2430 if residuals is not None: 2431 new_plots.append(residuals) 2432 2331 2433 # Update/generate plots 2332 2434 for plot in new_plots: 2333 2435 self.communicate.plotUpdateSignal.emit([plot]) 2334 2335 def complete2D(self, return_data):2336 """2337 Plot the current 2D data2338 """2339 fitted_data = self.logic.new2DPlot(return_data)2340 self.calculateResiduals(fitted_data)2341 self.model_data = fitted_data2342 2436 2343 2437 def calculateResiduals(self, fitted_data): … … 2470 2564 _, min, max = self.kernel_module.details[param_name] 2471 2565 2566 # Update local param dict 2567 self.poly_params[param_name + '.width'] = width 2568 self.poly_params[param_name + '.npts'] = npts 2569 self.poly_params[param_name + '.nsigmas'] = nsigs 2570 2472 2571 # Construct a row with polydisp. related variable. 2473 2572 # This will get added to the polydisp. model … … 2517 2616 def updateFunctionCaption(row): 2518 2617 # Utility function for update of polydispersity function name in the main model 2618 if not self.isCheckable(row): 2619 return 2620 self._model_model.blockSignals(True) 2519 2621 param_name = str(self._model_model.item(row, 0).text()) 2622 self._model_model.blockSignals(False) 2520 2623 if param_name != param.name: 2521 2624 return 2522 2625 # Modify the param value 2626 self._model_model.blockSignals(True) 2523 2627 if self.has_error_column: 2524 2628 # err column changes the indexing … … 2526 2630 else: 2527 2631 self._model_model.item(row, 0).child(0).child(0,4).setText(combo_string) 2632 self._model_model.blockSignals(False) 2528 2633 2529 2634 if combo_string == 'array': … … 2644 2749 param.units] 2645 2750 2751 self.magnet_params[param.name] = param.default 2752 2646 2753 FittingUtilities.addCheckedListToModel(model, checked_list) 2647 2754 … … 2683 2790 2684 2791 self.lstParams.setIndexWidget(shell_index, func) 2685 self._ last_model_row = self._model_model.rowCount()2792 self._n_shells_row = shell_row - 1 2686 2793 2687 2794 # Set the index to the state-kept value … … 2694 2801 """ 2695 2802 # Find row location of the combobox 2696 last_row = self._last_model_row2697 remove_rows = self._ model_model.rowCount() - last_row2803 first_row = self._n_shells_row + 1 2804 remove_rows = self._num_shell_params 2698 2805 2699 2806 if remove_rows > 1: 2700 self._model_model.removeRows(last_row, remove_rows) 2701 2702 FittingUtilities.addShellsToModel(self.model_parameters, self._model_model, index) 2807 self._model_model.removeRows(first_row, remove_rows) 2808 2809 new_rows = FittingUtilities.addShellsToModel( 2810 self.model_parameters, 2811 self._model_model, 2812 index, 2813 first_row, 2814 self.lstParams) 2815 2816 self._num_shell_params = len(new_rows) 2703 2817 self.current_shell_displayed = index 2704 2818 … … 3046 3160 formatted_output = FittingUtilities.formatParameters(param_list) 3047 3161 elif format == "Excel": 3048 formatted_output = FittingUtilities.formatParametersExcel(param_list )3162 formatted_output = FittingUtilities.formatParametersExcel(param_list[1:]) 3049 3163 elif format == "Latex": 3050 formatted_output = FittingUtilities.formatParametersLatex(param_list )3164 formatted_output = FittingUtilities.formatParametersLatex(param_list[1:]) 3051 3165 else: 3052 3166 raise AttributeError("Bad format specifier.") … … 3213 3327 self._poly_model.blockSignals(False) 3214 3328 3329 3330
Note: See TracChangeset
for help on using the changeset viewer.