Changeset 21e71f1 in sasview for src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
- Timestamp:
- Nov 21, 2018 6:39:24 AM (5 years ago)
- Branches:
- ESS_GUI, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
- Children:
- f2e199e
- Parents:
- 44c15fc (diff), fb39f28 (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
r7f41584 r21e71f1 52 52 TAB_POLY = 3 53 53 CATEGORY_DEFAULT = "Choose category..." 54 MODEL_DEFAULT = "Choose model..." 54 55 CATEGORY_STRUCTURE = "Structure Factor" 55 56 CATEGORY_CUSTOM = "Plugin Models" … … 574 575 # Signals from other widgets 575 576 self.communicate.customModelDirectoryChanged.connect(self.onCustomModelChange) 576 self.communicate.saveAnalysisSignal.connect(self.savePageState)577 #self.communicate.loadAnalysisSignal.connect(self.loadPageState)578 577 self.smearing_widget.smearingChangedSignal.connect(self.onSmearingOptionsUpdate) 579 578 … … 623 622 to_string = "to its current value" if num_rows == 1 else "to their current values" 624 623 has_constraints = any([self.rowHasConstraint(i) for i in rows]) 624 has_real_constraints = any([self.rowHasActiveConstraint(i) for i in rows]) 625 625 626 626 self.actionSelect = QtWidgets.QAction(self) … … 640 640 self.actionRemoveConstraint.setText(QtCore.QCoreApplication.translate("self", "Remove constraint")) 641 641 642 self.actionEditConstraint = QtWidgets.QAction(self) 643 self.actionEditConstraint.setObjectName("actionEditConstrain") 644 self.actionEditConstraint.setText(QtCore.QCoreApplication.translate("self", "Edit constraint")) 645 642 646 self.actionMultiConstrain = QtWidgets.QAction(self) 643 647 self.actionMultiConstrain.setObjectName("actionMultiConstrain") … … 654 658 if has_constraints: 655 659 menu.addAction(self.actionRemoveConstraint) 660 if num_rows == 1 and has_real_constraints: 661 menu.addAction(self.actionEditConstraint) 656 662 #if num_rows == 1: 657 663 # menu.addAction(self.actionEditConstraint) … … 664 670 self.actionConstrain.triggered.connect(self.addSimpleConstraint) 665 671 self.actionRemoveConstraint.triggered.connect(self.deleteConstraint) 672 self.actionEditConstraint.triggered.connect(self.editConstraint) 666 673 self.actionMutualMultiConstrain.triggered.connect(self.showMultiConstraint) 667 674 self.actionSelect.triggered.connect(self.selectParameters) … … 701 708 new_func = c_text.replace(param_used, updated_param_used) 702 709 constraint.func = new_func 710 constraint.value_ex = updated_param_used 703 711 # Which row is the constrained parameter in? 704 712 row = self.getRowFromName(constraint.param) 713 714 # what is the parameter to constraint to? 715 constraint.value = param_used 716 717 # Should the new constraint be validated? 718 constraint.validate = mc_widget.validate 705 719 706 720 # Create a new item and add the Constraint object as a child … … 799 813 self.communicate.statusBarUpdateSignal.emit('Constraint added') 800 814 815 def editConstraint(self): 816 """ 817 Delete constraints from selected parameters. 818 """ 819 params_list = [s.data() for s in self.lstParams.selectionModel().selectedRows() 820 if self.isCheckable(s.row())] 821 assert len(params_list) == 1 822 row = self.lstParams.selectionModel().selectedRows()[0].row() 823 constraint = self.getConstraintForRow(row) 824 # Create and display the widget for param1 and param2 825 mc_widget = MultiConstraint(self, params=params_list, constraint=constraint) 826 # Check if any of the parameters are polydisperse 827 if not np.any([FittingUtilities.isParamPolydisperse(p, self.model_parameters, is2D=self.is2D) for p in params_list]): 828 # no parameters are pd - reset the text to not show the warning 829 mc_widget.lblWarning.setText("") 830 if mc_widget.exec_() != QtWidgets.QDialog.Accepted: 831 return 832 833 constraint = Constraint() 834 c_text = mc_widget.txtConstraint.text() 835 836 # widget.params[0] is the parameter we're constraining 837 constraint.param = mc_widget.params[0] 838 # parameter should have the model name preamble 839 model_name = self.kernel_module.name 840 # param_used is the parameter we're using in constraining function 841 param_used = mc_widget.params[1] 842 # Replace param_used with model_name.param_used 843 updated_param_used = model_name + "." + param_used 844 # Update constraint with new values 845 constraint.func = c_text 846 constraint.value_ex = updated_param_used 847 constraint.value = param_used 848 # Should the new constraint be validated? 849 constraint.validate = mc_widget.validate 850 851 # Which row is the constrained parameter in? 852 row = self.getRowFromName(constraint.param) 853 854 # Create a new item and add the Constraint object as a child 855 self.addConstraintToRow(constraint=constraint, row=row) 856 801 857 def deleteConstraint(self): 802 858 """ … … 853 909 return None 854 910 911 def allParamNames(self): 912 """ 913 Returns a list of all parameter names defined on the current model 914 """ 915 all_params = self.kernel_module._model_info.parameters.kernel_parameters 916 all_param_names = [param.name for param in all_params] 917 # Assure scale and background are always included 918 if 'scale' not in all_param_names: 919 all_param_names.append('scale') 920 if 'background' not in all_param_names: 921 all_param_names.append('background') 922 return all_param_names 923 924 def paramHasConstraint(self, param=None): 925 """ 926 Finds out if the given parameter in the main model has a constraint child 927 """ 928 if param is None: return False 929 if param not in self.allParamNames(): return False 930 931 for row in range(self._model_model.rowCount()): 932 if self._model_model.item(row,0).text() != param: continue 933 return self.rowHasConstraint(row) 934 935 # nothing found 936 return False 937 855 938 def rowHasConstraint(self, row): 856 939 """ … … 1018 1101 Checks if the current model has magnetic scattering implemented 1019 1102 """ 1020 has_ params = False1103 has_mag_params = False 1021 1104 if self.kernel_module: 1022 1105 has_mag_params = len(self.kernel_module.magnetic_params) > 0 … … 1029 1112 model = self.cbModel.currentText() 1030 1113 1114 if model == MODEL_DEFAULT: 1115 # if the previous category was not the default, keep it. 1116 # Otherwise, just return 1117 if self._previous_model_index != 0: 1118 # We need to block signals, or else state changes on perceived unchanged conditions 1119 self.cbModel.blockSignals(True) 1120 self.cbModel.setCurrentIndex(self._previous_model_index) 1121 self.cbModel.blockSignals(False) 1122 return 1123 1031 1124 # Assure the control is active 1032 1125 if not self.cbModel.isEnabled(): … … 1035 1128 if not model: 1036 1129 return 1130 1131 self.chkMagnetism.setEnabled(self.canHaveMagnetism()) 1132 self.chkMagnetism.setEnabled(self.canHaveMagnetism()) 1133 self.tabFitting.setTabEnabled(TAB_MAGNETISM, self.chkMagnetism.isChecked() and self.canHaveMagnetism()) 1134 self._previous_model_index = self.cbModel.currentIndex() 1037 1135 1038 1136 # Reset parameters to fit … … 1213 1311 self._model_model.clear() 1214 1312 return 1215 1313 # Wipe out the parameter model 1314 self._model_model.clear() 1216 1315 # Safely clear and enable the model combo 1217 1316 self.cbModel.blockSignals(True) … … 1225 1324 model_list = self.master_category_dict[category] 1226 1325 # Populate the models combobox 1326 self.cbModel.blockSignals(True) 1327 self.cbModel.addItem(MODEL_DEFAULT) 1227 1328 self.cbModel.addItems(sorted([model for (model, _) in model_list])) 1329 self.cbModel.blockSignals(False) 1228 1330 1229 1331 def onPolyModelChange(self, top, bottom): … … 1937 2039 Emits plotRequestedSignal for all plots found in the given model under the provided item name. 1938 2040 """ 1939 fitpage_name = "" if self.tab_id is None else "M"+str(self.tab_id)2041 fitpage_name = self.kernel_module.name 1940 2042 plots = GuiUtils.plotsFromFilename(item_name, item_model) 1941 2043 # Has the fitted data been shown? … … 2425 2527 def isCheckable(self, row): 2426 2528 return self._model_model.item(row, 0).isCheckable() 2529 2530 def selectCheckbox(self, row): 2531 """ 2532 Select the checkbox in given row. 2533 """ 2534 assert 0<= row <= self._model_model.rowCount() 2535 index = self._model_model.index(row, 0) 2536 item = self._model_model.itemFromIndex(index) 2537 item.setCheckState(QtCore.Qt.Checked) 2427 2538 2428 2539 def checkboxSelected(self, item): … … 3430 3541 return report_logic.reportList() 3431 3542 3432 def savePageState(self):3433 """3434 Create and serialize local PageState3435 """3436 filepath = self.saveAsAnalysisFile()3437 if filepath is None or filepath == "":3438 return3439 3440 fitpage_state = self.getFitPage()3441 fitpage_state += self.getFitModel()3442 3443 with open(filepath, 'w') as statefile:3444 for line in fitpage_state:3445 statefile.write(str(line))3446 3447 self.communicate.statusBarUpdateSignal.emit('Analysis saved.')3448 3449 def saveAsAnalysisFile(self):3450 """3451 Show the save as... dialog and return the chosen filepath3452 """3453 default_name = "FitPage"+str(self.tab_id)+".fitv"3454 3455 wildcard = "fitv files (*.fitv)"3456 kwargs = {3457 'caption' : 'Save As',3458 'directory' : default_name,3459 'filter' : wildcard,3460 'parent' : None,3461 }3462 # Query user for filename.3463 filename_tuple = QtWidgets.QFileDialog.getSaveFileName(**kwargs)3464 filename = filename_tuple[0]3465 return filename3466 3467 3543 def loadPageStateCallback(self,state=None, datainfo=None, format=None): 3468 3544 """ … … 3549 3625 3550 3626 param_list.append(['is_data', str(self.data_is_loaded)]) 3551 if self.data_is_loaded: 3552 param_list.append(['data_id', str(self.logic.data.id)]) 3553 param_list.append(['data_name', str(self.logic.data.filename)]) 3554 3627 data_ids = [] 3628 filenames = [] 3629 if self.is_batch_fitting: 3630 for item in self.all_data: 3631 # need item->data->data_id 3632 data = GuiUtils.dataFromItem(item) 3633 data_ids.append(data.id) 3634 filenames.append(data.filename) 3635 else: 3636 if self.data_is_loaded: 3637 data_ids = [str(self.logic.data.id)] 3638 filenames = [str(self.logic.data.filename)] 3639 param_list.append(['is_batch_fitting', str(self.is_batch_fitting)]) 3640 param_list.append(['data_name', filenames]) 3641 param_list.append(['data_id', data_ids]) 3642 param_list.append(['tab_name', self.modelName()]) 3555 3643 # option tab 3556 3644 param_list.append(['q_range_min', str(self.q_range_min)]) … … 3583 3671 """ 3584 3672 param_list = [] 3673 if self.kernel_module is None: 3674 return param_list 3675 3585 3676 param_list.append(['model_name', str(self.cbModel.currentText())]) 3586 3677 … … 3622 3713 except: 3623 3714 pass 3624 3625 param_list.append([param_name, param_checked, param_value, param_error, param_min, param_max]) 3715 # Do we have any constraints on this parameter? 3716 constraint = self.getConstraintForRow(row) 3717 cons = () 3718 if constraint is not None: 3719 value = constraint.value 3720 func = constraint.func 3721 value_ex = constraint.value_ex 3722 param = constraint.param 3723 validate = constraint.validate 3724 3725 cons = (value, param, value_ex, validate, func) 3726 3727 param_list.append([param_name, param_checked, param_value,param_error, param_min, param_max, cons]) 3626 3728 3627 3729 def gatherPolyParams(row): … … 3687 3789 cb_text = cb.text() 3688 3790 3689 context = {}3690 3791 lines = cb_text.split(':') 3691 3792 if lines[0] != 'sasview_parameter_values': … … 3699 3800 line_dict[content[0]] = content[1:] 3700 3801 3802 self.updatePageWithParameters(line_dict) 3803 3804 def createPageForParameters(self, line_dict): 3805 """ 3806 Sets up page with requested model/str factor 3807 and fills it up with sent parameters 3808 """ 3809 if 'fitpage_category' in line_dict: 3810 self.cbCategory.setCurrentIndex(self.cbCategory.findText(line_dict['fitpage_category'][0])) 3811 if 'fitpage_model' in line_dict: 3812 self.cbModel.setCurrentIndex(self.cbModel.findText(line_dict['fitpage_model'][0])) 3813 if 'fitpage_structure' in line_dict: 3814 self.cbStructureFactor.setCurrentIndex(self.cbStructureFactor.findText(line_dict['fitpage_structure'][0])) 3815 3816 # Now that the page is ready for parameters, fill it up 3817 self.updatePageWithParameters(line_dict) 3818 3819 def updatePageWithParameters(self, line_dict): 3820 """ 3821 Update FitPage with parameters in line_dict 3822 """ 3823 if 'model_name' not in line_dict.keys(): 3824 return 3701 3825 model = line_dict['model_name'][0] 3702 3703 if 'model_name' not in line_dict.keys(): 3704 return False 3826 context = {} 3705 3827 3706 3828 if 'multiplicity' in line_dict.keys(): … … 3711 3833 self.updateMultiplicityCombo(multip) 3712 3834 3835 if 'tab_name' in line_dict.keys(): 3836 self.kernel_module.name = line_dict['tab_name'][0] 3713 3837 if 'polydisperse_params' in line_dict.keys(): 3714 3838 self.chkPolydispersity.setChecked(line_dict['polydisperse_params'][0]=='True') … … 3833 3957 ioffset = 0 3834 3958 joffset = 0 3835 if len(param_dict[param_name])> 4:3959 if len(param_dict[param_name])>5: 3836 3960 # error values are not editable - no need to update 3837 3961 ioffset = 1 … … 3846 3970 except: 3847 3971 pass 3972 3973 # constraints 3974 cons = param_dict[param_name][4+ioffset] 3975 if cons is not None and len(cons)==5: 3976 value = cons[0] 3977 param = cons[1] 3978 value_ex = cons[2] 3979 validate = cons[3] 3980 function = cons[4] 3981 constraint = Constraint() 3982 constraint.value = value 3983 constraint.func = function 3984 constraint.param = param 3985 constraint.value_ex = value_ex 3986 constraint.validate = validate 3987 self.addConstraintToRow(constraint=constraint, row=row) 3848 3988 3849 3989 self.setFocus()
Note: See TracChangeset
for help on using the changeset viewer.