Changeset dab3351 in sasview for src/sas/qtgui/Perspectives/PrInversion/PrInversionPerspective.py
- Timestamp:
- Oct 27, 2017 11:34:56 AM (7 years ago)
- Branches:
- ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
- Children:
- d1a4793
- Parents:
- bde1a6b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/Perspectives/PrInversion/PrInversionPerspective.py
rbde1a6b rdab3351 1 import sys 2 import logging 1 3 import numpy as np 2 4 … … 13 15 # pr inversion calculation elements 14 16 from sas.sascalc.pr.invertor import Invertor 15 from sas.sasgui.perspectives.pr import pr_thread as pr_thread16 17 17 18 … … 52 53 # p(r) calculator 53 54 self._calculator = Invertor() 55 self._last_calculator = None 56 self.calc_thread = None 57 self.estimation_thread = None 54 58 55 59 self.model = QtGui.QStandardItemModel(self) … … 100 104 # self.dataList.currentIndexChanged.connect(self.displayChange) 101 105 self.calculateButton.clicked.connect(self._calculation) 102 self.statusButton.clicked.connect(self.status)103 106 self.helpButton.clicked.connect(self.help) 104 107 self.estimateBgd.toggled.connect(self.toggleBgd) 105 108 self.manualBgd.toggled.connect(self.toggleBgd) 109 self.regConstantSuggestionButton.clicked.connect(self.acceptAlpha) 110 self.noOfTermsSuggestionButton.clicked.connect(self.acceptNoTerms) 106 111 self.explorerButton.clicked.connect(self.openExplorerWindow) 107 112 self.model.itemChanged.connect(self.model_changed) … … 151 156 # Main Buttons 152 157 self.mapper.addMapping(self.calculateButton, WIDGETS.W_CALCULATE) 153 self.mapper.addMapping(self.statusButton, WIDGETS.W_STATUS)154 158 self.mapper.addMapping(self.helpButton, WIDGETS.W_HELP) 155 159 … … 203 207 """ 204 208 if self._has_data: 205 self.statusButton.setEnabled(True)206 209 self.explorerButton.setEnabled(True) 207 210 self.calculateButton.setEnabled(True) … … 209 212 self.calculateButton.setEnabled(False) 210 213 self.explorerButton.setEnabled(False) 211 self.statusButton.setEnabled(False)212 214 213 215 def populateDataComboBox(self, filename): … … 219 221 self.dataList.addItem(qt_item) 220 222 221 ###################################################################### 222 # GUI Actions 223 def acceptNoTerms(self): 224 """Send estimated no of terms to input""" 225 self.model.setItem(WIDGETS.W_NO_TERMS, QtGui.QStandardItem( 226 self.noOfTermsSuggestionButton.text())) 227 228 def acceptAlpha(self): 229 """Send estimated alpha to input""" 230 self.model.setItem(WIDGETS.W_REGULARIZATION, QtGui.QStandardItem( 231 self.regConstantSuggestionButton.text())) 232 233 ###################################################################### 234 # GUI Interaction Events 223 235 224 236 def _calculation(self): … … 226 238 Calculate the P(r) for every data set in the data list 227 239 """ 228 # TODO: Run the calculations 229 pass 240 # TODO: Set all invertor values before calculation 241 self._calculator.__setattr__("qmin", UI.TabbedPrInversionUI._fromUtf8( 242 self.minQInput.text())) 243 self.startThread() 230 244 231 245 def model_changed(self): … … 235 249 self.mapper.toFirst() 236 250 # TODO: Update plots, etc. 237 238 def status(self):239 """240 Show the status of the calculations241 """242 # TODO: Status - is this even needed/wanted?243 pass244 251 245 252 def help(self): … … 314 321 QtGui.QStandardItem(str(data_object.x.max()))) 315 322 316 # TODO: Get value estimates 317 no_terms, alpha, _ = self._calculator.estimate_numterms( 318 self._calculator) 319 self.noOfTermsSuggestionButton.setText( 320 QtCore.QString(str(no_terms))) 321 self.noOfTermsSuggestionButton.setEnabled(True) 322 self.regConstantSuggestionButton.setText(QtCore.QString(str(alpha))) 323 self.regConstantSuggestionButton.setEnabled(True) 323 # Estimate initial values from data 324 self.performEstimate() 325 326 # TODO: Plot data on load 324 327 325 328 # TODO: Only load in the 1st data until batch mode is working 329 # TODO: Thus, the break 326 330 break 331 332 ###################################################################### 333 # Thread Creators 334 335 def startThread(self): 336 """ 337 Start a calculation thread 338 """ 339 from PrThread import CalcPr 340 341 # If a thread is already started, stop it 342 if self.calc_thread is not None and self.calc_thread.isrunning(): 343 self.calc_thread.stop() 344 pr = self._calculator.clone() 345 nfunc = int(UI.TabbedPrInversionUI._fromUtf8( 346 self.noOfTermsInput.text())) 347 self.calc_thread = CalcPr(pr, nfunc, 348 error_func=self._threadError, 349 completefn=self._completed, updatefn=None) 350 self.calc_thread.queue() 351 self.calc_thread.ready(2.5) 352 353 def performEstimateNT(self): 354 """ 355 Perform parameter estimation 356 """ 357 from PrThread import EstimateNT 358 359 # If a thread is already started, stop it 360 if (self.estimation_thread is not None and 361 self.estimation_thread.isrunning()): 362 self.estimation_thread.stop() 363 pr = self._calculator.clone() 364 # Skip the slit settings for the estimation 365 # It slows down the application and it doesn't change the estimates 366 pr.slit_height = 0.0 367 pr.slit_width = 0.0 368 nfunc = int(UI.TabbedPrInversionUI._fromUtf8( 369 self.noOfTermsInput.text())) 370 self.estimation_thread = EstimateNT(pr, nfunc, 371 error_func=self._threadError, 372 completefn=self._estimateNTCompleted, 373 updatefn=None) 374 self.estimation_thread.queue() 375 self.estimation_thread.ready(2.5) 376 377 def performEstimate(self): 378 """ 379 Perform parameter estimation 380 """ 381 from PrThread import EstimatePr 382 383 # If a thread is already started, stop it 384 if (self.estimation_thread is not None and 385 self.estimation_thread.isrunning()): 386 self.estimation_thread.stop() 387 pr = self._calculator.clone() 388 nfunc = int(UI.TabbedPrInversionUI._fromUtf8( 389 self.noOfTermsInput.text())) 390 self.estimation_thread = EstimatePr(pr, nfunc, 391 error_func=self._threadError, 392 completefn=self._estimateCompleted, 393 updatefn=None) 394 self.estimation_thread.queue() 395 self.estimation_thread.ready(2.5) 396 397 ###################################################################### 398 # Thread Complete 399 400 def _estimateCompleted(self, alpha, message, elapsed): 401 """ 402 Parameter estimation completed, 403 display the results to the user 404 405 :param alpha: estimated best alpha 406 :param elapsed: computation time 407 """ 408 # Save useful info 409 self.model.setItem(WIDGETS.W_COMP_TIME, 410 QtGui.QStandardItem(str(elapsed))) 411 self.regConstantSuggestionButton.setText(QtCore.QString(str(alpha))) 412 self.regConstantSuggestionButton.setEnabled(True) 413 if message is not None: 414 logging.info(message) 415 self.performEstimateNT() 416 417 def _estimateNTCompleted(self, nterms, alpha, message, elapsed): 418 """ 419 Parameter estimation completed, 420 display the results to the user 421 422 :param alpha: estimated best alpha 423 :param nterms: estimated number of terms 424 :param elapsed: computation time 425 426 """ 427 # Save useful info 428 self.noOfTermsSuggestionButton.setText(QtCore.QString(str(nterms))) 429 self.noOfTermsSuggestionButton.setEnabled(True) 430 self.regConstantSuggestionButton.setText(QtCore.QString(str(alpha))) 431 self.regConstantSuggestionButton.setEnabled(True) 432 self.model.setItem(WIDGETS.W_COMP_TIME, 433 QtGui.QStandardItem(str(elapsed))) 434 if message is not None: 435 logging.info(message) 436 pass 437 438 def _completed(self, out, cov, pr, elapsed): 439 """ 440 Method called with the results when the inversion is done 441 442 :param out: output coefficient for the base functions 443 :param cov: covariance matrix 444 :param pr: Invertor instance 445 :param elapsed: time spent computing 446 447 """ 448 # Save useful info 449 # Keep a copy of the last result 450 self._last_calculator = pr.clone() 451 452 # TODO: Append to data dictionary 453 # self._data_list.append({s}) 454 455 # Save Pr invertor 456 self._calculator = pr 457 cov = np.ascontiguousarray(cov) 458 459 # Show result on control panel 460 461 self.model.setItem(WIDGETS.W_RG, QtGui.QStandardItem(str(pr.rg(out)))) 462 self.model.setItem(WIDGETS.W_I_ZERO, 463 QtGui.QStandardItem(str(pr.iq0(out)))) 464 self.model.setItem(WIDGETS.W_BACKGROUND_INPUT, 465 QtGui.QStandardItem("{:.2g}".format(pr.background))) 466 self.model.setItem(WIDGETS.W_BACKGROUND_OUTPUT, 467 QtGui.QStandardItem(str(pr.background))) 468 self.model.setItem(WIDGETS.W_CHI_SQUARED, 469 QtGui.QStandardItem(str(pr.chi2))) 470 self.model.setItem(WIDGETS.W_COMP_TIME, 471 QtGui.QStandardItem(str(elapsed))) 472 self.model.setItem(WIDGETS.W_OSCILLATION, 473 QtGui.QStandardItem(str(pr.oscillations(out)))) 474 self.model.setItem(WIDGETS.W_POS_FRACTION, 475 QtGui.QStandardItem(str(pr.get_positive(out)))) 476 self.model.setItem(WIDGETS.W_SIGMA_POS_FRACTION, 477 QtGui.QStandardItem(str(pr.get_pos_err(out, cov)))) 478 479 # TODO: Show plots 480 # Show I(q) fit 481 # self.show_iq(out, self._calculator) 482 # Show P(r) fit 483 # self.show_pr(out, self._calculator, cov) 484 485 def _threadError(self, error): 486 """ 487 Call-back method for calculation errors 488 """ 489 logging.warning(error) 490 491 def show_data(self, path=None, data=None, reset=False): 492 """ 493 Show data read from a file 494 495 :param path: file path 496 :param reset: if True all other plottables will be cleared 497 498 """ 499 if data is not None: 500 try: 501 pr = self._create_file_pr(data) 502 except: 503 status = "Problem reading data: %s" % sys.exc_value 504 raise RuntimeError, status 505 506 # If the file contains nothing, just return 507 if pr is None: 508 raise RuntimeError, "Loaded data is invalid" 509 510 self._calculator = pr 511 512 # Make a plot of I(q) data 513 if self._calculator.err is None: 514 logging.log(self._calculator.err) 515 else: 516 # TODO: Do something 517 pass 518 # Get Q range 519 #self.control_panel.q_min = min(self._calculator.x) 520 #self.control_panel.q_max = max(self._calculator.x)
Note: See TracChangeset
for help on using the changeset viewer.