- Timestamp:
- Sep 14, 2018 7:21:00 AM (6 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:
- 14ec7dfd
- Parents:
- 3c4f02e (diff), 86d3207 (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. - Location:
- src/sas
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/MainWindow/GuiManager.py
r5b144c6 r768387e0 118 118 self.dockedFilesWidget.setWidget(self.filesWidget) 119 119 120 # Disable maximize/minimize and close buttons 121 self.dockedFilesWidget.setFeatures(QDockWidget.NoDockWidgetFeatures) 122 123 #self._workspace.workspace.addDockWidget(Qt.LeftDockWidgetArea, self.dockedFilesWidget) 120 # Modify menu items on widget visibility change 121 self.dockedFilesWidget.visibilityChanged.connect(self.updateContextMenus) 122 124 123 self._workspace.addDockWidget(Qt.LeftDockWidgetArea, self.dockedFilesWidget) 125 124 self._workspace.resizeDocks([self.dockedFilesWidget], [305], Qt.Horizontal) … … 164 163 logger.error("%s: could not load SasView models") 165 164 logger.error(traceback.format_exc()) 165 166 def updateContextMenus(self, visible=False): 167 """ 168 Modify the View/Data Explorer menu item text on widget visibility 169 """ 170 if visible: 171 self._workspace.actionHide_DataExplorer.setText("Hide Data Explorer") 172 else: 173 self._workspace.actionHide_DataExplorer.setText("Show Data Explorer") 166 174 167 175 def statusBarSetup(self): … … 427 435 self._workspace.actionStartup_Settings.triggered.connect(self.actionStartup_Settings) 428 436 self._workspace.actionCategory_Manager.triggered.connect(self.actionCategory_Manager) 437 self._workspace.actionHide_DataExplorer.triggered.connect(self.actionHide_DataExplorer) 429 438 # Tools 430 439 self._workspace.actionData_Operation.triggered.connect(self.actionData_Operation) … … 617 626 pass 618 627 628 def actionHide_DataExplorer(self): 629 """ 630 Toggle Data Explorer vsibility 631 """ 632 if self.dockedFilesWidget.isVisible(): 633 #self._workspace.actionHide_DataExplorer.setText("Show Data Explorer") 634 self.dockedFilesWidget.setVisible(False) 635 else: 636 #self._workspace.actionHide_DataExplorer.setText("Hide Data Explorer") 637 self.dockedFilesWidget.setVisible(True) 638 pass 639 619 640 def actionStartup_Settings(self): 620 641 """ -
src/sas/qtgui/MainWindow/UI/MainWindowUI.ui
r33b3e4d r768387e0 74 74 <addaction name="separator"/> 75 75 <addaction name="actionHide_Toolbar"/> 76 <addaction name="actionHide_DataExplorer"/> 76 77 <addaction name="separator"/> 77 78 <addaction name="actionStartup_Settings"/> … … 552 553 </property> 553 554 </action> 555 <action name="actionHide_DataExplorer"> 556 <property name="text"> 557 <string>Hide Data Explorer</string> 558 </property> 559 </action> 554 560 </widget> 555 561 <resources/> -
src/sas/qtgui/MainWindow/UnitTesting/GuiManagerTest.py
r144fe21 r768387e0 53 53 self.assertIsInstance(self.manager.dockedFilesWidget, QDockWidget) 54 54 self.assertIsInstance(self.manager.dockedFilesWidget.widget(), DataExplorerWindow) 55 self.assertEqual(self.manager.dockedFilesWidget.features(), QDockWidget.NoDockWidgetFeatures)56 55 self.assertEqual(self.manager._workspace.dockWidgetArea(self.manager.dockedFilesWidget), Qt.LeftDockWidgetArea) 57 56 -
src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
r557fc498 r86d3207 28 28 from sas.qtgui.Plotting.PlotterData import Data1D 29 29 from sas.qtgui.Plotting.PlotterData import Data2D 30 from sas.qtgui.Plotting.Plotter import PlotterWidget 30 31 31 32 from sas.qtgui.Perspectives.Fitting.UI.FittingWidgetUI import Ui_FittingWidgetUI … … 2825 2826 item4 = QtGui.QStandardItem() 2826 2827 2827 self._model_model.appendRow([item1, item2, item3, item4]) 2828 # cell 4: SLD button 2829 item5 = QtGui.QStandardItem() 2830 button = QtWidgets.QPushButton() 2831 button.setText("Show SLD Profile") 2832 2833 self._model_model.appendRow([item1, item2, item3, item4, item5]) 2828 2834 2829 2835 # Beautify the row: span columns 2-4 2830 2836 shell_row = self._model_model.rowCount() 2831 2837 shell_index = self._model_model.index(shell_row-1, 1) 2838 button_index = self._model_model.index(shell_row-1, 4) 2832 2839 2833 2840 self.lstParams.setIndexWidget(shell_index, func) 2841 self.lstParams.setIndexWidget(button_index, button) 2834 2842 self._n_shells_row = shell_row - 1 2835 2843 … … 2858 2866 func.currentTextChanged.connect(self.modifyShellsInList) 2859 2867 2868 # Respond to button press 2869 button.clicked.connect(self.onShowSLDProfile) 2870 2860 2871 # Available range of shells displayed in the combobox 2861 2872 func.addItems([str(i) for i in range(shell_min, shell_max+1)]) … … 2877 2888 index = 0 2878 2889 logger.error("Multiplicity incorrect! Setting to 0") 2879 2890 self.kernel_module.multiplicity = index 2880 2891 if remove_rows > 1: 2881 2892 self._model_model.removeRows(first_row, remove_rows) … … 2903 2914 self.setPolyModel() 2904 2915 self.setMagneticModel() 2916 2917 def onShowSLDProfile(self): 2918 """ 2919 Show a quick plot of SLD profile 2920 """ 2921 # get profile data 2922 x, y = self.kernel_module.getProfile() 2923 y *= 1.0e6 2924 profile_data = Data1D(x=x, y=y) 2925 profile_data.name = "SLD" 2926 profile_data.scale = 'linear' 2927 profile_data.symbol = 'Line' 2928 profile_data.hide_error = True 2929 profile_data._xaxis = "R(\AA)" 2930 profile_data._yaxis = "SLD(10^{-6}\AA^{-2})" 2931 2932 plotter = PlotterWidget(self, quickplot=True) 2933 plotter.data = profile_data 2934 plotter.showLegend = True 2935 plotter.plot(hide_error=True, marker='-') 2936 2937 self.plot_widget = QtWidgets.QWidget() 2938 self.plot_widget.setWindowTitle("Scattering Length Density Profile") 2939 layout = QtWidgets.QVBoxLayout() 2940 layout.addWidget(plotter) 2941 self.plot_widget.setLayout(layout) 2942 self.plot_widget.show() 2905 2943 2906 2944 def setInteractiveElements(self, enabled=True): -
src/sas/qtgui/Perspectives/Inversion/DMaxExplorerWidget.py
rb0ba43e r9f2f713 42 42 self.parent = parent 43 43 44 self.setWindowTitle("D ââExplorer")44 self.setWindowTitle("Dmax Explorer") 45 45 46 46 self.pr_state = pr_state … … 116 116 bck = [] 117 117 chi2 = [] 118 118 plotable_xs = [] #Introducing this to make sure size of x and y for plotting is the same.8 119 119 try: 120 120 dmin = float(self.model.item(W.DMIN).text()) … … 128 128 129 129 original = self.pr_state.d_max 130 130 131 for x in xs: 131 132 self.pr_state.d_max = x … … 140 141 bck.append(self.pr_state.background) 141 142 chi2.append(self.pr_state.chi2) 143 plotable_xs.append(x) 142 144 except Exception as ex: 143 145 # This inversion failed, skip this D_max value … … 155 157 logger.error(msg) 156 158 157 plotter = self.model.item(W.VARIABLE).text() 158 y_label = y_unit = "" 159 plotter = self.dependentVariable.currentText() 159 160 x_label = "D_{max}" 160 161 x_unit = "A" … … 188 189 y_unit = "a.u." 189 190 190 data = Data1D( xs, ys)191 data = Data1D(plotable_xs, ys) 191 192 if self.hasPlot: 192 self.plot.removePlot( None)193 self.plot.removePlot(data.name) 193 194 self.hasPlot = True 194 195 data.title = plotter -
src/sas/qtgui/Perspectives/Inversion/InversionLogic.py
r6da860a r3c4f02e 111 111 new_plot.title = title 112 112 113 new_plot.symbol = 'Line' 114 new_plot.hide_error = True 115 113 116 return new_plot 114 117 -
src/sas/qtgui/Perspectives/Inversion/InversionPerspective.py
r855e7ad r4b7d322 44 44 estimateSignal = QtCore.pyqtSignal(tuple) 45 45 estimateNTSignal = QtCore.pyqtSignal(tuple) 46 estimateDynamicNTSignal = QtCore.pyqtSignal(tuple) 47 estimateDynamicSignal = QtCore.pyqtSignal(tuple) 46 48 calculateSignal = QtCore.pyqtSignal(tuple) 47 49 … … 195 197 self.model.itemChanged.connect(self.model_changed) 196 198 self.estimateNTSignal.connect(self._estimateNTUpdate) 199 self.estimateDynamicNTSignal.connect(self._estimateDynamicNTUpdate) 200 self.estimateDynamicSignal.connect(self._estimateDynamicUpdate) 197 201 self.estimateSignal.connect(self._estimateUpdate) 198 202 self.calculateSignal.connect(self._calculateUpdate) 203 204 self.maxDistanceInput.textEdited.connect(self.performEstimateDynamic) 199 205 200 206 def setupMapper(self): … … 310 316 and not self.isCalculating) 311 317 self.removeButton.setEnabled(self.logic.data_is_loaded) 312 self.explorerButton.setEnabled(self.logic.data_is_loaded 313 and np.all(self.logic.data.dy != 0)) 318 self.explorerButton.setEnabled(self.logic.data_is_loaded) 314 319 self.stopButton.setVisible(self.isCalculating) 315 320 self.regConstantSuggestionButton.setEnabled( … … 458 463 self._calculator.set_qmin(qmin) 459 464 self._calculator.set_qmax(qmax) 465 if np.size(self.logic.data.dy) == 0 or np.all(self.logic.data.dy) == 0: 466 self.logic.data.dy = self._calculator.add_errors(self.logic.data.y) 460 467 self.updateDataList(data) 461 468 self.populateDataComboBox(self.logic.data.filename, data) … … 502 509 self.dataPlot = self._dataList[data_ref].get(DICT_KEYS[2]) 503 510 self.performEstimate() 511 512 def updateDynamicGuiValues(self): 513 pr = self._calculator 514 alpha = self._calculator.suggested_alpha 515 self.model.setItem(WIDGETS.W_MAX_DIST, 516 QtGui.QStandardItem("{:.4g}".format(pr.get_dmax()))) 517 self.regConstantSuggestionButton.setText("{:-3.2g}".format(alpha)) 518 self.noOfTermsSuggestionButton.setText( 519 "{:n}".format(self.nTermsSuggested)) 520 521 self.enableButtons() 504 522 505 523 def updateGuiValues(self): … … 521 539 self.model.setItem(WIDGETS.W_MAX_DIST, 522 540 QtGui.QStandardItem("{:.4g}".format(pr.get_dmax()))) 523 self.regConstantSuggestionButton.setText("{:-3.2g}".format(alpha))524 self.noOfTermsSuggestionButton.setText(525 "{:n}".format(self.nTermsSuggested))526 541 527 542 if isinstance(pr.chi2, np.ndarray): … … 674 689 self.estimationThreadNT.ready(2.5) 675 690 691 def performEstimateDynamicNT(self): 692 """ 693 Perform parameter estimation 694 """ 695 from .Thread import EstimateNT 696 697 self.updateCalculator() 698 699 # If a thread is already started, stop it 700 self.stopEstimateNTThread() 701 702 pr = self._calculator.clone() 703 # Skip the slit settings for the estimation 704 # It slows down the application and it doesn't change the estimates 705 pr.slit_height = 0.0 706 pr.slit_width = 0.0 707 nfunc = self.getNFunc() 708 709 self.estimationThreadNT = EstimateNT(pr, nfunc, 710 error_func=self._threadError, 711 completefn=self._estimateDynamicNTCompleted, 712 updatefn=None) 713 self.estimationThreadNT.queue() 714 self.estimationThreadNT.ready(2.5) 715 676 716 def stopEstimateNTThread(self): 677 717 if (self.estimationThreadNT is not None and … … 696 736 self.estimationThread.ready(2.5) 697 737 738 def performEstimateDynamic(self): 739 """ 740 Perform parameter estimation 741 """ 742 from .Thread import EstimatePr 743 744 # If a thread is already started, stop it 745 self.stopEstimationThread() 746 747 self.estimationThread = EstimatePr(self._calculator.clone(), 748 self.getNFunc(), 749 error_func=self._threadError, 750 completefn=self._estimateDynamicCompleted, 751 updatefn=None) 752 self.estimationThread.queue() 753 self.estimationThread.ready(2.5) 754 698 755 def stopEstimationThread(self): 699 756 """ Stop the estimation thread if it exists and is running """ … … 708 765 ''' Send a signal to the main thread for model update''' 709 766 self.estimateSignal.emit((alpha, message, elapsed)) 767 768 def _estimateDynamicCompleted(self, alpha, message, elapsed): 769 ''' Send a signal to the main thread for model update''' 770 self.estimateDynamicSignal.emit((alpha, message, elapsed)) 710 771 711 772 def _estimateUpdate(self, output_tuple): … … 723 784 logger.info(message) 724 785 self.performEstimateNT() 786 self.performEstimateDynamicNT() 787 788 def _estimateDynamicUpdate(self, output_tuple): 789 """ 790 Parameter estimation completed, 791 display the results to the user 792 793 :param alpha: estimated best alpha 794 :param elapsed: computation time 795 """ 796 alpha, message, elapsed = output_tuple 797 self._calculator.alpha = alpha 798 self._calculator.elapsed += self._calculator.elapsed 799 if message: 800 logger.info(message) 801 self.performEstimateDynamicNT() 725 802 726 803 def _estimateNTCompleted(self, nterms, alpha, message, elapsed): 727 804 ''' Send a signal to the main thread for model update''' 728 805 self.estimateNTSignal.emit((nterms, alpha, message, elapsed)) 806 807 def _estimateDynamicNTCompleted(self, nterms, alpha, message, elapsed): 808 ''' Send a signal to the main thread for model update''' 809 self.estimateDynamicNTSignal.emit((nterms, alpha, message, elapsed)) 729 810 730 811 def _estimateNTUpdate(self, output_tuple): … … 750 831 self.startThread() 751 832 833 def _estimateDynamicNTUpdate(self, output_tuple): 834 """ 835 Parameter estimation completed, 836 display the results to the user 837 838 :param alpha: estimated best alpha 839 :param nterms: estimated number of terms 840 :param elapsed: computation time 841 """ 842 nterms, alpha, message, elapsed = output_tuple 843 self._calculator.elapsed += elapsed 844 self._calculator.suggested_alpha = alpha 845 self.nTermsSuggested = nterms 846 # Save useful info 847 self.updateDynamicGuiValues() 848 if message: 849 logger.info(message) 850 if self.isBatch: 851 self.acceptAlpha() 852 self.acceptNoTerms() 853 self.startThread() 854 752 855 def _calculateCompleted(self, out, cov, pr, elapsed): 753 856 ''' Send a signal to the main thread for model update''' -
src/sas/qtgui/Perspectives/Inversion/UI/DMaxExplorer.ui
r8f83719f rcfd61f2 7 7 <x>0</x> 8 8 <y>0</y> 9 <width> 394</width>10 <height> 426</height>9 <width>586</width> 10 <height>538</height> 11 11 </rect> 12 12 </property> … … 21 21 <property name="orientation"> 22 22 <enum>Qt::Vertical</enum> 23 </property>24 <property name="sizeHint" stdset="0">25 <size>26 <width>20</width>27 <height>305</height>28 </size>29 23 </property> 30 24 </spacer> -
src/sas/qtgui/Plotting/Plotter.py
r5b144c6 rd0952de 84 84 if self.data.ytransform is None: 85 85 self.data.ytransform = 'log10(y)' 86 86 #Added condition to Dmax explorer from P(r) perspective 87 if self.data._xaxis == 'D_{max}': 88 self.xscale = 'linear' 87 89 # Transform data if required. 88 90 if transform and (self.data.xtransform is not None or self.data.ytransform is not None): -
src/sas/sascalc/pr/invertor.py
rb8080e1 reeea6a3 71 71 A[j][i] = (Fourier transformed base function for point j) 72 72 73 We the mchoose a number of r-points, n_r, to evaluate the second73 We then choose a number of r-points, n_r, to evaluate the second 74 74 derivative of P(r) at. This is used as our regularization term. 75 75 For a vector r of length n_r, the following n_r rows are set to :: … … 144 144 x, y, err, d_max, q_min, q_max and alpha 145 145 """ 146 if 146 if name == 'x': 147 147 if 0.0 in value: 148 148 msg = "Invertor: one of your q-values is zero. " … … 227 227 return None 228 228 229 def add_errors(self, yvalues): 230 """ 231 Adds errors to data set is they are not avaialble 232 :return: 233 """ 234 stats_errors = np.zeros(len(yvalues)) 235 for i in range(len(yvalues)): 236 # Scale the error so that we can fit over several decades of Q 237 scale = 0.05 * np.sqrt(yvalues[i]) 238 min_err = 0.01 * yvalues[i] 239 stats_errors[i] = scale * np.sqrt(np.fabs(yvalues[i])) + min_err 240 logger.warning("Simulated errors have been added to the data set\n") 241 return stats_errors 242 229 243 def clone(self): 230 244 """ … … 268 282 A[i][j] = (Fourier transformed base function for point j) 269 283 270 We the mchoose a number of r-points, n_r, to evaluate the second284 We then choose a number of r-points, n_r, to evaluate the second 271 285 derivative of P(r) at. This is used as our regularization term. 272 286 For a vector r of length n_r, the following n_r rows are set to ::
Note: See TracChangeset
for help on using the changeset viewer.