- Timestamp:
- Sep 13, 2018 8:17:46 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:
- eeea6a3
- Parents:
- 13da5f5 (diff), 1a15ada (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:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py
r8b745c36 r1a15ada 23 23 24 24 poly_header_tooltips = ['Select parameter for fitting', 25 'Enter polydispersity ratio (STD/mean). ' 25 'Enter polydispersity ratio (Std deviation/mean).\n'+ 26 'For angles this can be either std deviation or full width (for uniform distributions) in degrees', 26 27 'STD: standard deviation from the mean value', 27 28 'Enter minimum value for parameter', -
src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py
rf712bf30 r1a15ada 393 393 394 394 # Test tooltips 395 self.assertEqual(len(self.widget._poly_model.header_tooltips), 8)395 self.assertEqual(len(self.widget._poly_model.header_tooltips), 9) 396 396 397 397 header_tooltips = ['Select parameter for fitting', 398 'Enter polydispersity ratio (STD/mean). ' 399 'STD: standard deviation from the mean value', 400 'Enter minimum value for parameter', 401 'Enter maximum value for parameter', 402 'Enter number of points for parameter', 403 'Enter number of sigmas parameter', 404 'Select distribution function', 405 'Select filename with user-definable distribution'] 398 'Enter polydispersity ratio (Std deviation/mean).\n'+ 399 'For angles this can be either std deviation or full width (for uniform distributions) in degrees', 400 'STD: standard deviation from the mean value', 401 'Enter minimum value for parameter', 402 'Enter maximum value for parameter', 403 'Enter number of points for parameter', 404 'Enter number of sigmas parameter', 405 'Select distribution function', 406 'Select filename with user-definable distribution'] 406 407 for column, tooltip in enumerate(header_tooltips): 407 408 self.assertEqual(self.widget._poly_model.headerData( column, … … 908 909 self.assertFalse(self.widget.tabFitting.isTabEnabled(4)) 909 910 910 def testReadFitPage2D(self): 911 # to be fixed after functionality is ready 912 def notestReadFitPage2D(self): 911 913 """ 912 914 Read in the fitpage object and restore state -
src/sas/qtgui/Perspectives/Inversion/DMaxExplorerWidget.py
rb0ba43e re908916 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 … … 188 190 y_unit = "a.u." 189 191 190 data = Data1D( xs, ys)192 data = Data1D(plotable_xs, ys) 191 193 if self.hasPlot: 192 194 self.plot.removePlot(None) -
src/sas/qtgui/Perspectives/Inversion/InversionPerspective.py
r2b8286c r28965e9 43 43 estimateSignal = QtCore.pyqtSignal(tuple) 44 44 estimateNTSignal = QtCore.pyqtSignal(tuple) 45 estimateDynamicNTSignal = QtCore.pyqtSignal(tuple) 46 estimateDynamicSignal = QtCore.pyqtSignal(tuple) 45 47 calculateSignal = QtCore.pyqtSignal(tuple) 46 48 … … 194 196 self.model.itemChanged.connect(self.model_changed) 195 197 self.estimateNTSignal.connect(self._estimateNTUpdate) 198 self.estimateDynamicNTSignal.connect(self._estimateDynamicNTUpdate) 199 self.estimateDynamicSignal.connect(self._estimateDynamicUpdate) 196 200 self.estimateSignal.connect(self._estimateUpdate) 197 201 self.calculateSignal.connect(self._calculateUpdate) 202 203 self.maxDistanceInput.textEdited.connect(self.performEstimateDynamic) 198 204 199 205 def setupMapper(self): … … 309 315 and not self.isCalculating) 310 316 self.removeButton.setEnabled(self.logic.data_is_loaded) 311 self.explorerButton.setEnabled(self.logic.data_is_loaded 312 and np.all(self.logic.data.dy != 0)) 317 self.explorerButton.setEnabled(self.logic.data_is_loaded) 313 318 self.stopButton.setVisible(self.isCalculating) 314 319 self.regConstantSuggestionButton.setEnabled( … … 501 506 self.dataPlot = self._dataList[data_ref].get(DICT_KEYS[2]) 502 507 self.performEstimate() 508 509 def updateDynamicGuiValues(self): 510 pr = self._calculator 511 alpha = self._calculator.suggested_alpha 512 self.model.setItem(WIDGETS.W_MAX_DIST, 513 QtGui.QStandardItem("{:.4g}".format(pr.get_dmax()))) 514 self.regConstantSuggestionButton.setText("{:-3.2g}".format(alpha)) 515 self.noOfTermsSuggestionButton.setText( 516 "{:n}".format(self.nTermsSuggested)) 517 518 self.enableButtons() 503 519 504 520 def updateGuiValues(self): … … 520 536 self.model.setItem(WIDGETS.W_MAX_DIST, 521 537 QtGui.QStandardItem("{:.4g}".format(pr.get_dmax()))) 522 self.regConstantSuggestionButton.setText("{:-3.2g}".format(alpha))523 self.noOfTermsSuggestionButton.setText(524 "{:n}".format(self.nTermsSuggested))525 538 526 539 if isinstance(pr.chi2, np.ndarray): … … 671 684 self.estimationThreadNT.ready(2.5) 672 685 686 def performEstimateDynamicNT(self): 687 """ 688 Perform parameter estimation 689 """ 690 from .Thread import EstimateNT 691 692 self.updateCalculator() 693 694 # If a thread is already started, stop it 695 self.stopEstimateNTThread() 696 697 pr = self._calculator.clone() 698 # Skip the slit settings for the estimation 699 # It slows down the application and it doesn't change the estimates 700 pr.slit_height = 0.0 701 pr.slit_width = 0.0 702 nfunc = self.getNFunc() 703 704 self.estimationThreadNT = EstimateNT(pr, nfunc, 705 error_func=self._threadError, 706 completefn=self._estimateDynamicNTCompleted, 707 updatefn=None) 708 self.estimationThreadNT.queue() 709 self.estimationThreadNT.ready(2.5) 710 673 711 def stopEstimateNTThread(self): 674 712 if (self.estimationThreadNT is not None and … … 693 731 self.estimationThread.ready(2.5) 694 732 733 def performEstimateDynamic(self): 734 """ 735 Perform parameter estimation 736 """ 737 from .Thread import EstimatePr 738 739 # If a thread is already started, stop it 740 self.stopEstimationThread() 741 742 self.estimationThread = EstimatePr(self._calculator.clone(), 743 self.getNFunc(), 744 error_func=self._threadError, 745 completefn=self._estimateDynamicCompleted, 746 updatefn=None) 747 self.estimationThread.queue() 748 self.estimationThread.ready(2.5) 749 695 750 def stopEstimationThread(self): 696 751 """ Stop the estimation thread if it exists and is running """ … … 705 760 ''' Send a signal to the main thread for model update''' 706 761 self.estimateSignal.emit((alpha, message, elapsed)) 762 763 def _estimateDynamicCompleted(self, alpha, message, elapsed): 764 ''' Send a signal to the main thread for model update''' 765 self.estimateDynamicSignal.emit((alpha, message, elapsed)) 707 766 708 767 def _estimateUpdate(self, output_tuple): … … 720 779 logger.info(message) 721 780 self.performEstimateNT() 781 self.performEstimateDynamicNT() 782 783 def _estimateDynamicUpdate(self, output_tuple): 784 """ 785 Parameter estimation completed, 786 display the results to the user 787 788 :param alpha: estimated best alpha 789 :param elapsed: computation time 790 """ 791 alpha, message, elapsed = output_tuple 792 self._calculator.alpha = alpha 793 self._calculator.elapsed += self._calculator.elapsed 794 if message: 795 logger.info(message) 796 self.performEstimateDynamicNT() 722 797 723 798 def _estimateNTCompleted(self, nterms, alpha, message, elapsed): 724 799 ''' Send a signal to the main thread for model update''' 725 800 self.estimateNTSignal.emit((nterms, alpha, message, elapsed)) 801 802 def _estimateDynamicNTCompleted(self, nterms, alpha, message, elapsed): 803 ''' Send a signal to the main thread for model update''' 804 self.estimateDynamicNTSignal.emit((nterms, alpha, message, elapsed)) 726 805 727 806 def _estimateNTUpdate(self, output_tuple): … … 747 826 self.startThread() 748 827 828 def _estimateDynamicNTUpdate(self, output_tuple): 829 """ 830 Parameter estimation completed, 831 display the results to the user 832 833 :param alpha: estimated best alpha 834 :param nterms: estimated number of terms 835 :param elapsed: computation time 836 """ 837 nterms, alpha, message, elapsed = output_tuple 838 self._calculator.elapsed += elapsed 839 self._calculator.suggested_alpha = alpha 840 self.nTermsSuggested = nterms 841 # Save useful info 842 self.updateDynamicGuiValues() 843 if message: 844 logger.info(message) 845 if self.isBatch: 846 self.acceptAlpha() 847 self.acceptNoTerms() 848 self.startThread() 849 749 850 def _calculateCompleted(self, out, cov, pr, elapsed): 750 851 ''' Send a signal to the main thread for model update''' -
src/sas/sascalc/pr/invertor.py
rb8080e1 r13da5f5 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 """ … … 244 258 invertor.x = self.x 245 259 invertor.y = self.y 246 invertor.err = self.err 260 if np.size(self.err) == 0 or np.all(self.err) == 0: 261 invertor.err = self.add_errors(self.y) 262 else: 263 invertor.err = self.err 247 264 invertor.est_bck = self.est_bck 248 265 invertor.background = self.background … … 268 285 A[i][j] = (Fourier transformed base function for point j) 269 286 270 We the mchoose a number of r-points, n_r, to evaluate the second287 We then choose a number of r-points, n_r, to evaluate the second 271 288 derivative of P(r) at. This is used as our regularization term. 272 289 For a vector r of length n_r, the following n_r rows are set to :: … … 289 306 # Reset the background value before proceeding 290 307 # self.background = 0.0 308 if np.size(self.err) == 0 or np.all(self.err) == 0: 309 self.err = self.add_errors(self.y) 291 310 if not self.est_bck: 292 311 self.y -= self.background
Note: See TracChangeset
for help on using the changeset viewer.