- Timestamp:
- Mar 28, 2019 6:54:29 AM (6 years ago)
- Branches:
- ESS_GUI_bumps_abstraction
- Children:
- 740a738
- Parents:
- aa47ea5
- git-author:
- Ingo Breßler <dev@…> (03/28/19 06:51:02)
- git-committer:
- Ingo Breßler <dev@…> (03/28/19 06:54:29)
- Location:
- src/sas/qtgui/Perspectives/Fitting
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/Perspectives/Fitting/FittingOptions.py
raa47ea5 r04a269f 20 20 # Set the default optimizer 21 21 22 def configToBumps(fittingMethod): 23 """ 24 Writes the user settings of given fitting method back to be bumps module where it is used 25 once the 'fit' button is hit in the GUI. 26 """ 27 # assert isinstance(fittingMethod, FittingMethod) # FIXME once FittingMethod is known here 28 # self.config.values[self.current_fitter_id][option] = new_value 29 fitConfig = bumps.options.FIT_CONFIG 30 fitConfig.selected_id = fittingMethod.shortName 31 for param in fittingMethod.params.values(): 32 fitConfig.values[fittingMethod.shortName][param.shortName] = param.value 33 34 def parse_int(value): 35 """ 36 Converts user input to integer numbers. (from bumps) 37 """ 38 float_value = float(value) 39 if int(float_value) != float_value: 40 raise ValueError("integer expected") 41 return int(float_value) 42 43 class ChoiceList(object): 44 """ 45 Validates user input for a distinct number of options. 46 """ 47 def __init__(self, *choices): 48 self.choices = choices 49 def __call__(self, value): 50 if not value in self.choices: 51 raise ValueError('invalid option "%s": use %s' 52 % (value, '|'.join(self.choices))) 53 else: 54 return value 55 22 56 class FittingMethodParameter: 57 """ 58 Descriptive meta data of a single parameter of an optimizer. 59 """ 23 60 _shortName = None 24 61 _longName = None … … 122 159 return [fm.shortName for fm in self._methods.values()] 123 160 124 def __getitem__(self, name):125 return self._methods[ name]161 def __getitem__(self, longName): 162 return self._methods[longName] 126 163 127 164 @property … … 152 189 fit_option_changed = QtCore.pyqtSignal(str) 153 190 # storing of fitting methods here for now, dependencies might indicate a better place later 154 fittingMethods = None 191 _fittingMethods = None 192 193 @property 194 def fittingMethods(self): 195 return self._fittingMethods 155 196 156 197 def __init__(self, parent=None, config=None): … … 168 209 169 210 # Fill up the algorithm combo, based on what BUMPS says is available 170 self. fittingMethods = FittingMethods()211 self._fittingMethods = FittingMethods() 171 212 # option 1: hardcode the list of bumps fitting methods according to forms 172 213 # option 2: create forms dynamically based on selected fitting methods … … 202 243 def assignValidators(self): 203 244 """ 204 Use options.FIT_FIELDS to assert which line edit gets what validator205 """ 206 f or option in bumps.options.FIT_FIELDS.keys():207 (f_name, f_type) = bumps.options.FIT_FIELDS[option]245 Sets the appropriate validators to the line edits as defined by FittingMethodParameter 246 """ 247 fm = self.fittingMethods[str(self.currentOptimizer)] 248 for param in fm.params.values(): 208 249 validator = None 209 if type( f_type) == types.FunctionType:250 if type(param.type) == types.FunctionType: 210 251 validator = QtGui.QIntValidator() 211 252 validator.setBottom(0) 212 elif f_type == float:253 elif param.type == float: 213 254 validator = GuiUtils.DoubleValidator() 214 255 validator.setBottom(0) 215 256 else: 216 257 continue 217 for fitter_id in self.fittingMethods.ids: 218 line_edit = self.widgetFromOption(str(option), current_fitter=str(fitter_id)) 219 if hasattr(line_edit, 'setValidator') and validator is not None: 220 line_edit.setValidator(validator) 221 line_edit.textChanged.connect(self.check_state) 222 line_edit.textChanged.emit(line_edit.text()) 258 line_edit = self.paramWidget(fm, param.shortName) 259 if hasattr(line_edit, 'setValidator') and validator is not None: 260 line_edit.setValidator(validator) 261 line_edit.textChanged.connect(self.check_state) 262 line_edit.textChanged.emit(line_edit.text()) 223 263 224 264 def check_state(self, *args, **kwargs): … … 240 280 """ 241 281 # Find the algorithm ID from name 242 selectedName = str(self.c bAlgorithm.currentText())282 selectedName = str(self.currentOptimizer) 243 283 if selectedName in self.fittingMethods.longNames: 244 284 self.current_fitter_id = self.fittingMethods[selectedName].shortName … … 268 308 self.stackedWidget.setCurrentIndex(index_for_this_id) 269 309 270 self.updateWidgetFrom Bumps(self.current_fitter_id)310 self.updateWidgetFromConfig() 271 311 272 312 self.assignValidators() … … 278 318 self.previous_index = index 279 319 320 def paramWidget(self, fittingMethod, paramShortName): 321 """ 322 Returns the widget associated to a FittingMethodParameter. 323 """ 324 if paramShortName not in fittingMethod.params: 325 return None 326 widget_name = 'self.'+paramShortName+'_'+fittingMethod.shortName 327 widget = None 328 try: 329 widget = eval(widget_name) 330 except AttributeError: 331 pass 332 return widget 333 280 334 def onApply(self): 281 335 """ 282 336 Update the fitter object 283 337 """ 284 options = self.config.values[self.current_fitter_id] 285 for option in options.keys(): 286 # Find the widget name of the option 287 # e.g. 'samples' for 'dream' is 'self.samples_dream' 288 widget_name = 'self.'+option+'_'+self.current_fitter_id 289 try: 290 line_edit = eval(widget_name) 291 except AttributeError: 292 # Skip bumps monitors 293 continue 338 fm = self.fittingMethods[str(self.currentOptimizer)] 339 for param in fm.params.values(): 340 line_edit = self.paramWidget(fm, param.shortName) 294 341 if line_edit is None or not isinstance(line_edit, QtWidgets.QLineEdit): 295 342 continue … … 299 346 tooltip = "<html><b>Please enter valid values in all fields.</html>" 300 347 QtWidgets.QToolTip.showText(line_edit.mapToGlobal( 301 QtCore.QPoint(line_edit.rect().right(), line_edit.rect().bottom() + 2)), tooltip) 348 QtCore.QPoint(line_edit.rect().right(), line_edit.rect().bottom() + 2)), 349 tooltip) 302 350 return 303 351 304 # Notify the perspective, so the window title is updated 305 self.fit_option_changed.emit(self.cbAlgorithm.currentText()) 306 307 def bumpsUpdate(option): 308 """ 309 Utility method for bumps state update 310 """ 311 widget = self.widgetFromOption(option) 352 # update config values from widgets before any notification is sent 353 for param in fm.params.values(): 354 widget = self.paramWidget(fm, param.shortName) 312 355 if widget is None: 313 return356 continue 314 357 try: 315 358 if isinstance(widget, QtWidgets.QComboBox): … … 320 363 except ValueError: 321 364 new_value = float(widget.text()) 322 #new_value = widget.currentText() if isinstance(widget, QtWidgets.QComboBox) \ 323 # else float(widget.text()) 324 self.config.values[self.current_fitter_id][option] = new_value 365 fm.params[param.shortName].value = new_value 325 366 except ValueError: 326 367 # Don't update bumps if widget has bad data 327 368 self.reject 328 369 329 # Update the BUMPS singleton 330 [bumpsUpdate(o) for o in self.config.values[self.current_fitter_id].keys()] 370 # Notify the perspective, so the window title is updated 371 self.fit_option_changed.emit(self.cbAlgorithm.currentText()) 372 configToBumps(fm) # write the current settings to bumps module 331 373 self.close() 332 374 … … 345 387 webbrowser.open('file://' + os.path.realpath(help_location)) 346 388 347 def widgetFromOption(self, option_id, current_fitter=None): 348 """ 349 returns widget's element linked to the given option_id 350 """ 351 if current_fitter is None: 352 current_fitter = self.current_fitter_id 353 if option_id not in list(bumps.options.FIT_FIELDS.keys()): return None 354 option = option_id + '_' + current_fitter 355 if not hasattr(self, option): return None 356 return eval('self.' + option) 357 358 def getResults(self): 389 @property 390 def currentOptimizer(self): 359 391 """ 360 392 Sends back the current choice of parameters 361 393 """ 362 algorithm = self.cbAlgorithm.currentText() 363 return algorithm 364 365 def updateWidgetFromBumps(self, fitter_id): 394 return self.cbAlgorithm.currentText() 395 396 def updateWidgetFromConfig(self): 366 397 """ 367 398 Given the ID of the current optimizer, fetch the values 368 399 and update the widget 369 400 """ 370 options = self.config.values[fitter_id]371 for option in options.keys():401 fm = self.fittingMethods[str(self.currentOptimizer)] 402 for param in fm.params.values(): 372 403 # Find the widget name of the option 373 404 # e.g. 'samples' for 'dream' is 'self.samples_dream' 374 widget_name = 'self.'+option+'_'+fitter_id 375 if option not in bumps.options.FIT_FIELDS: 376 return 377 if isinstance(bumps.options.FIT_FIELDS[option][1], bumps.options.ChoiceList): 405 widget_name = 'self.'+param.shortName+'_'+(fm.shortName) 406 if isinstance(param.type, ChoiceList): 378 407 control = eval(widget_name) 379 control.setCurrentIndex(control.findText(str( options[option])))408 control.setCurrentIndex(control.findText(str(param.value))) 380 409 else: 381 eval(widget_name).setText(str(options[option])) 382 383 pass 410 eval(widget_name).setText(str(param.value)) 411 -
src/sas/qtgui/Perspectives/Fitting/FittingPerspective.py
r14e1ff0 r04a269f 39 39 self.maxIndex = 1 40 40 41 # The default optimizer42 self.optimizer = 'Levenberg-Marquardt'43 44 41 # Dataset index -> Fitting tab mapping 45 42 self.dataToFitTab = {} … … 72 69 73 70 # Fit options - uniform for all tabs 74 self.fit_options = options.FIT_CONFIG75 self.fit_options_widget = FittingOptions(self, config=self.fit_options)76 self. fit_options.selected_id = fitters.LevenbergMarquardtFit.id71 self.fit_options_widget = FittingOptions(self) 72 # The default optimizer 73 self.optimizer = self.fit_options_widget.currentOptimizer 77 74 78 75 # Listen to GUI Manager signal updating fit options … … 95 92 Update the window title with the current optimizer name 96 93 """ 97 self.optimizer = self.fit_options.selected_name98 94 self.setWindowTitle('Fit panel - Active Fitting Optimizer: %s' % self.optimizer) 99 95 … … 368 364 React to the fitting algorithm change by modifying window title 369 365 """ 370 fitter = [f.id for f in options.FITTERS if f.name == str(fit_engine)][0]366 self.optimizer = self.fit_options_widget.currentOptimizer 371 367 # set the optimizer 372 self.fit_options.selected_id = str(fitter)373 368 # Update the title 374 369 self.updateWindowTitle()
Note: See TracChangeset
for help on using the changeset viewer.