Changeset 2385397 in sasview


Ignore:
Timestamp:
Sep 13, 2018 8:17:46 AM (2 months ago)
Author:
wojciech
Branches:
ESS_GUI, ESS_GUI_Pr_fixes, ESS_GUI_project_save
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.
Message:

Merge branch 'ESS_GUI' of https://github.com/SasView/sasview into ESS_GUI_Pr_fixes

Location:
src/sas
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py

    r8b745c36 r1a15ada  
    2323 
    2424poly_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', 
    2627                        'STD: standard deviation from the mean value', 
    2728                        'Enter minimum value for parameter', 
  • src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py

    rf712bf30 r1a15ada  
    393393 
    394394        # Test tooltips 
    395         self.assertEqual(len(self.widget._poly_model.header_tooltips), 8) 
     395        self.assertEqual(len(self.widget._poly_model.header_tooltips), 9) 
    396396 
    397397        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'] 
    406407        for column, tooltip in enumerate(header_tooltips): 
    407408             self.assertEqual(self.widget._poly_model.headerData( column, 
     
    908909        self.assertFalse(self.widget.tabFitting.isTabEnabled(4)) 
    909910 
    910     def testReadFitPage2D(self): 
     911    # to be fixed after functionality is ready 
     912    def notestReadFitPage2D(self): 
    911913        """ 
    912914        Read in the fitpage object and restore state 
  • src/sas/qtgui/Perspectives/Inversion/DMaxExplorerWidget.py

    rb0ba43e re908916  
    4242        self.parent = parent 
    4343 
    44         self.setWindowTitle("Dₐₓ Explorer") 
     44        self.setWindowTitle("Dmax Explorer") 
    4545 
    4646        self.pr_state = pr_state 
     
    116116        bck = [] 
    117117        chi2 = [] 
    118  
     118        plotable_xs = [] #Introducing this to make sure size of x and y for plotting is the same.8 
    119119        try: 
    120120            dmin = float(self.model.item(W.DMIN).text()) 
     
    128128 
    129129        original = self.pr_state.d_max 
     130 
    130131        for x in xs: 
    131132            self.pr_state.d_max = x 
     
    140141                bck.append(self.pr_state.background) 
    141142                chi2.append(self.pr_state.chi2) 
     143                plotable_xs.append(x) 
    142144            except Exception as ex: 
    143145                # This inversion failed, skip this D_max value 
     
    188190            y_unit = "a.u." 
    189191 
    190         data = Data1D(xs, ys) 
     192        data = Data1D(plotable_xs, ys) 
    191193        if self.hasPlot: 
    192194            self.plot.removePlot(None) 
  • src/sas/qtgui/Perspectives/Inversion/InversionPerspective.py

    r2b8286c r28965e9  
    4343    estimateSignal = QtCore.pyqtSignal(tuple) 
    4444    estimateNTSignal = QtCore.pyqtSignal(tuple) 
     45    estimateDynamicNTSignal = QtCore.pyqtSignal(tuple) 
     46    estimateDynamicSignal = QtCore.pyqtSignal(tuple) 
    4547    calculateSignal = QtCore.pyqtSignal(tuple) 
    4648 
     
    194196        self.model.itemChanged.connect(self.model_changed) 
    195197        self.estimateNTSignal.connect(self._estimateNTUpdate) 
     198        self.estimateDynamicNTSignal.connect(self._estimateDynamicNTUpdate) 
     199        self.estimateDynamicSignal.connect(self._estimateDynamicUpdate) 
    196200        self.estimateSignal.connect(self._estimateUpdate) 
    197201        self.calculateSignal.connect(self._calculateUpdate) 
     202 
     203        self.maxDistanceInput.textEdited.connect(self.performEstimateDynamic) 
    198204 
    199205    def setupMapper(self): 
     
    309315                                            and not self.isCalculating) 
    310316        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) 
    313318        self.stopButton.setVisible(self.isCalculating) 
    314319        self.regConstantSuggestionButton.setEnabled( 
     
    501506        self.dataPlot = self._dataList[data_ref].get(DICT_KEYS[2]) 
    502507        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() 
    503519 
    504520    def updateGuiValues(self): 
     
    520536        self.model.setItem(WIDGETS.W_MAX_DIST, 
    521537                           QtGui.QStandardItem("{:.4g}".format(pr.get_dmax()))) 
    522         self.regConstantSuggestionButton.setText("{:-3.2g}".format(alpha)) 
    523         self.noOfTermsSuggestionButton.setText( 
    524             "{:n}".format(self.nTermsSuggested)) 
    525538 
    526539        if isinstance(pr.chi2, np.ndarray): 
     
    671684        self.estimationThreadNT.ready(2.5) 
    672685 
     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 
    673711    def stopEstimateNTThread(self): 
    674712        if (self.estimationThreadNT is not None and 
     
    693731        self.estimationThread.ready(2.5) 
    694732 
     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 
    695750    def stopEstimationThread(self): 
    696751        """ Stop the estimation thread if it exists and is running """ 
     
    705760        ''' Send a signal to the main thread for model update''' 
    706761        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)) 
    707766 
    708767    def _estimateUpdate(self, output_tuple): 
     
    720779            logger.info(message) 
    721780        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() 
    722797 
    723798    def _estimateNTCompleted(self, nterms, alpha, message, elapsed): 
    724799        ''' Send a signal to the main thread for model update''' 
    725800        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)) 
    726805 
    727806    def _estimateNTUpdate(self, output_tuple): 
     
    747826            self.startThread() 
    748827 
     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 
    749850    def _calculateCompleted(self, out, cov, pr, elapsed): 
    750851        ''' Send a signal to the main thread for model update''' 
  • src/sas/sascalc/pr/invertor.py

    rb8080e1 r13da5f5  
    7171        A[j][i] = (Fourier transformed base function for point j) 
    7272 
    73     We them choose a number of r-points, n_r, to evaluate the second 
     73    We then choose a number of r-points, n_r, to evaluate the second 
    7474    derivative of P(r) at. This is used as our regularization term. 
    7575    For a vector r of length n_r, the following n_r rows are set to :: 
     
    144144        x, y, err, d_max, q_min, q_max and alpha 
    145145        """ 
    146         if   name == 'x': 
     146        if name == 'x': 
    147147            if 0.0 in value: 
    148148                msg = "Invertor: one of your q-values is zero. " 
     
    227227        return None 
    228228 
     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 
    229243    def clone(self): 
    230244        """ 
     
    244258        invertor.x = self.x 
    245259        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 
    247264        invertor.est_bck = self.est_bck 
    248265        invertor.background = self.background 
     
    268285            A[i][j] = (Fourier transformed base function for point j) 
    269286 
    270         We them choose a number of r-points, n_r, to evaluate the second 
     287        We then choose a number of r-points, n_r, to evaluate the second 
    271288        derivative of P(r) at. This is used as our regularization term. 
    272289        For a vector r of length n_r, the following n_r rows are set to :: 
     
    289306        # Reset the background value before proceeding 
    290307        # 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) 
    291310        if not self.est_bck: 
    292311            self.y -= self.background 
Note: See TracChangeset for help on using the changeset viewer.