Changes in / [fc5d2d7f:d7adf97] in sasview


Ignore:
Location:
src/sas
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/Perspectives/Inversion/DMaxExplorerWidget.py

    rb0ba43e r9f2f713  
    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 
     
    155157            logger.error(msg) 
    156158 
    157         plotter = self.model.item(W.VARIABLE).text() 
    158         y_label = y_unit = "" 
     159        plotter = self.dependentVariable.currentText() 
    159160        x_label = "D_{max}" 
    160161        x_unit = "A" 
     
    188189            y_unit = "a.u." 
    189190 
    190         data = Data1D(xs, ys) 
     191        data = Data1D(plotable_xs, ys) 
    191192        if self.hasPlot: 
    192             self.plot.removePlot(None) 
     193            self.plot.removePlot(data.name) 
    193194        self.hasPlot = True 
    194195        data.title = plotter 
  • src/sas/qtgui/Perspectives/Inversion/InversionLogic.py

    r6da860a r3c4f02e  
    111111            new_plot.title = title 
    112112 
     113        new_plot.symbol = 'Line' 
     114        new_plot.hide_error = True 
     115 
    113116        return new_plot 
    114117 
  • src/sas/qtgui/Perspectives/Inversion/InversionPerspective.py

    r9ce69ec r9ce69ec  
    4444    estimateSignal = QtCore.pyqtSignal(tuple) 
    4545    estimateNTSignal = QtCore.pyqtSignal(tuple) 
     46    estimateDynamicNTSignal = QtCore.pyqtSignal(tuple) 
     47    estimateDynamicSignal = QtCore.pyqtSignal(tuple) 
    4648    calculateSignal = QtCore.pyqtSignal(tuple) 
    4749 
     
    5355 
    5456        self._manager = parent 
     57        self._parent = parent 
    5558        self.communicate = parent.communicator() 
    5659        self.communicate.dataDeletedSignal.connect(self.removeData) 
     
    110113        # Set up the Widget Map 
    111114        self.setupMapper() 
     115 
     116        #Hidding calculate all buton 
     117        self.calculateAllButton.setVisible(False) 
    112118        # Set base window state 
    113119        self.setupWindow() 
     
    120126 
    121127    def allowBatch(self): 
    122         return True 
     128        return False 
    123129 
    124130    def setClosable(self, value=True): 
     
    195201        self.model.itemChanged.connect(self.model_changed) 
    196202        self.estimateNTSignal.connect(self._estimateNTUpdate) 
     203        self.estimateDynamicNTSignal.connect(self._estimateDynamicNTUpdate) 
     204        self.estimateDynamicSignal.connect(self._estimateDynamicUpdate) 
    197205        self.estimateSignal.connect(self._estimateUpdate) 
    198206        self.calculateSignal.connect(self._calculateUpdate) 
     207 
     208        self.maxDistanceInput.textEdited.connect(self.performEstimateDynamic) 
    199209 
    200210    def setupMapper(self): 
     
    310320                                            and not self.isCalculating) 
    311321        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)) 
     322        self.explorerButton.setEnabled(self.logic.data_is_loaded) 
    314323        self.stopButton.setVisible(self.isCalculating) 
    315324        self.regConstantSuggestionButton.setEnabled( 
     
    454463            # Create initial internal mappings 
    455464            self.logic.data = GuiUtils.dataFromItem(data) 
     465            if not isinstance(self.logic.data, Data1D): 
     466                msg = "P(r) perspective works for 1D data only" 
     467                logger.warning(msg) 
     468                continue 
    456469            # Estimate q range 
    457470            qmin, qmax = self.logic.computeDataRange() 
    458471            self._calculator.set_qmin(qmin) 
    459472            self._calculator.set_qmax(qmax) 
     473            if np.size(self.logic.data.dy) == 0 or np.all(self.logic.data.dy) == 0: 
     474                self.logic.data.dy = self._calculator.add_errors(self.logic.data.y) 
    460475            self.updateDataList(data) 
    461476            self.populateDataComboBox(self.logic.data.filename, data) 
    462477        self.dataList.setCurrentIndex(len(self.dataList) - 1) 
    463         self.setCurrentData(data) 
     478        #Checking for 1D again to mitigate the case when 2D data is last on the data list 
     479        if isinstance(self.logic.data, Data1D): 
     480            self.setCurrentData(data) 
    464481 
    465482    def updateDataList(self, dataRef): 
     
    502519        self.dataPlot = self._dataList[data_ref].get(DICT_KEYS[2]) 
    503520        self.performEstimate() 
     521 
     522    def updateDynamicGuiValues(self): 
     523        pr = self._calculator 
     524        alpha = self._calculator.suggested_alpha 
     525        self.model.setItem(WIDGETS.W_MAX_DIST, 
     526                            QtGui.QStandardItem("{:.4g}".format(pr.get_dmax()))) 
     527        self.regConstantSuggestionButton.setText("{:-3.2g}".format(alpha)) 
     528        self.noOfTermsSuggestionButton.setText( 
     529             "{:n}".format(self.nTermsSuggested)) 
     530 
     531        self.enableButtons() 
    504532 
    505533    def updateGuiValues(self): 
     
    521549        self.model.setItem(WIDGETS.W_MAX_DIST, 
    522550                           QtGui.QStandardItem("{:.4g}".format(pr.get_dmax()))) 
    523         self.regConstantSuggestionButton.setText("{:-3.2g}".format(alpha)) 
    524         self.noOfTermsSuggestionButton.setText( 
    525             "{:n}".format(self.nTermsSuggested)) 
    526551 
    527552        if isinstance(pr.chi2, np.ndarray): 
     
    638663 
    639664        pr = self._calculator.clone() 
    640         nfunc = self.getNFunc() 
    641         self.calcThread = CalcPr(pr, nfunc, 
     665        #Making sure that nfunc and alpha parameters are correctly initialized 
     666        pr.suggested_alpha = self._calculator.alpha 
     667        self.calcThread = CalcPr(pr, self.nTermsSuggested, 
    642668                                 error_func=self._threadError, 
    643669                                 completefn=self._calculateCompleted, 
     
    672698                                             error_func=self._threadError, 
    673699                                             completefn=self._estimateNTCompleted, 
     700                                             updatefn=None) 
     701        self.estimationThreadNT.queue() 
     702        self.estimationThreadNT.ready(2.5) 
     703 
     704    def performEstimateDynamicNT(self): 
     705        """ 
     706        Perform parameter estimation 
     707        """ 
     708        from .Thread import EstimateNT 
     709 
     710        self.updateCalculator() 
     711 
     712        # If a thread is already started, stop it 
     713        self.stopEstimateNTThread() 
     714 
     715        pr = self._calculator.clone() 
     716        # Skip the slit settings for the estimation 
     717        # It slows down the application and it doesn't change the estimates 
     718        pr.slit_height = 0.0 
     719        pr.slit_width = 0.0 
     720        nfunc = self.getNFunc() 
     721 
     722        self.estimationThreadNT = EstimateNT(pr, nfunc, 
     723                                             error_func=self._threadError, 
     724                                             completefn=self._estimateDynamicNTCompleted, 
    674725                                             updatefn=None) 
    675726        self.estimationThreadNT.queue() 
     
    698749        self.estimationThread.ready(2.5) 
    699750 
     751    def performEstimateDynamic(self): 
     752        """ 
     753            Perform parameter estimation 
     754        """ 
     755        from .Thread import EstimatePr 
     756 
     757        # If a thread is already started, stop it 
     758        self.stopEstimationThread() 
     759 
     760        self.estimationThread = EstimatePr(self._calculator.clone(), 
     761                                           self.getNFunc(), 
     762                                           error_func=self._threadError, 
     763                                           completefn=self._estimateDynamicCompleted, 
     764                                           updatefn=None) 
     765        self.estimationThread.queue() 
     766        self.estimationThread.ready(2.5) 
     767 
    700768    def stopEstimationThread(self): 
    701769        """ Stop the estimation thread if it exists and is running """ 
     
    710778        ''' Send a signal to the main thread for model update''' 
    711779        self.estimateSignal.emit((alpha, message, elapsed)) 
     780 
     781    def _estimateDynamicCompleted(self, alpha, message, elapsed): 
     782        ''' Send a signal to the main thread for model update''' 
     783        self.estimateDynamicSignal.emit((alpha, message, elapsed)) 
    712784 
    713785    def _estimateUpdate(self, output_tuple): 
     
    725797            logger.info(message) 
    726798        self.performEstimateNT() 
     799        self.performEstimateDynamicNT() 
     800 
     801    def _estimateDynamicUpdate(self, output_tuple): 
     802        """ 
     803        Parameter estimation completed, 
     804        display the results to the user 
     805 
     806        :param alpha: estimated best alpha 
     807        :param elapsed: computation time 
     808        """ 
     809        alpha, message, elapsed = output_tuple 
     810        self._calculator.alpha = alpha 
     811        self._calculator.elapsed += self._calculator.elapsed 
     812        if message: 
     813            logger.info(message) 
     814        self.performEstimateDynamicNT() 
    727815 
    728816    def _estimateNTCompleted(self, nterms, alpha, message, elapsed): 
    729817        ''' Send a signal to the main thread for model update''' 
    730818        self.estimateNTSignal.emit((nterms, alpha, message, elapsed)) 
     819 
     820    def _estimateDynamicNTCompleted(self, nterms, alpha, message, elapsed): 
     821        ''' Send a signal to the main thread for model update''' 
     822        self.estimateDynamicNTSignal.emit((nterms, alpha, message, elapsed)) 
    731823 
    732824    def _estimateNTUpdate(self, output_tuple): 
     
    752844            self.startThread() 
    753845 
     846    def _estimateDynamicNTUpdate(self, output_tuple): 
     847        """ 
     848        Parameter estimation completed, 
     849        display the results to the user 
     850 
     851        :param alpha: estimated best alpha 
     852        :param nterms: estimated number of terms 
     853        :param elapsed: computation time 
     854        """ 
     855        nterms, alpha, message, elapsed = output_tuple 
     856        self._calculator.elapsed += elapsed 
     857        self._calculator.suggested_alpha = alpha 
     858        self.nTermsSuggested = nterms 
     859        # Save useful info 
     860        self.updateDynamicGuiValues() 
     861        if message: 
     862            logger.info(message) 
     863        if self.isBatch: 
     864            self.acceptAlpha() 
     865            self.acceptNoTerms() 
     866            self.startThread() 
     867 
    754868    def _calculateCompleted(self, out, cov, pr, elapsed): 
    755869        ''' Send a signal to the main thread for model update''' 
  • src/sas/qtgui/Perspectives/Inversion/UI/DMaxExplorer.ui

    r8f83719f rcfd61f2  
    77    <x>0</x> 
    88    <y>0</y> 
    9     <width>394</width> 
    10     <height>426</height> 
     9    <width>586</width> 
     10    <height>538</height> 
    1111   </rect> 
    1212  </property> 
     
    2121       <property name="orientation"> 
    2222        <enum>Qt::Vertical</enum> 
    23        </property> 
    24        <property name="sizeHint" stdset="0"> 
    25         <size> 
    26          <width>20</width> 
    27          <height>305</height> 
    28         </size> 
    2923       </property> 
    3024      </spacer> 
  • src/sas/qtgui/Perspectives/Inversion/UI/TabbedInversionUI.ui

    r72ecbdf2 r68dc2873  
    77    <x>0</x> 
    88    <y>0</y> 
    9     <width>390</width> 
    10     <height>409</height> 
     9    <width>446</width> 
     10    <height>480</height> 
    1111   </rect> 
    1212  </property> 
     
    740740      <widget class="QPushButton" name="calculateAllButton"> 
    741741       <property name="enabled"> 
    742         <bool>true</bool> 
     742        <bool>false</bool> 
    743743       </property> 
    744744       <property name="sizePolicy"> 
  • src/sas/qtgui/Plotting/Plotter.py

    r5b144c6 rd0952de  
    8484            if self.data.ytransform is None: 
    8585                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' 
    8789            # Transform data if required. 
    8890            if transform and (self.data.xtransform is not None or self.data.ytransform is not None): 
  • src/sas/qtgui/Utilities/GridPanel.py

    raed0532 r4fbf0db  
    5454        # Fill in the table from input data 
    5555        self.setupTable(widget=self.tblParams, data=output_data) 
     56        #TODO: This is not what was inteded to be. 
    5657        if output_data is not None: 
    5758            # Set a table tooltip describing the model 
    58             model_name = output_data[0][0].model.id 
     59            model_name = list(output_data.keys())[0] 
    5960            self.tabWidget.setTabToolTip(0, model_name) 
    6061 
     
    418419    def __init__(self, parent = None, output_data=None): 
    419420 
    420         super(BatchInversionOutputPanel, self).__init__(parent, output_data) 
     421        super(BatchInversionOutputPanel, self).__init__(parent._parent, output_data) 
    421422        _translate = QtCore.QCoreApplication.translate 
    422423        self.setWindowTitle(_translate("GridPanelUI", "Batch P(r) Results")) 
    423424 
    424     def setupTable(self, data): 
     425    def setupTable(self, widget=None,  data=None): 
    425426        """ 
    426427        Create tablewidget items and show them, based on params 
     
    433434                      'Calc. Time [sec]'] 
    434435 
     436        if data is None: 
     437            return 
    435438        keys = data.keys() 
    436439        rows = len(keys) 
  • src/sas/sascalc/pr/invertor.py

    rb8080e1 reeea6a3  
    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        """ 
     
    268282            A[i][j] = (Fourier transformed base function for point j) 
    269283 
    270         We them choose a number of r-points, n_r, to evaluate the second 
     284        We then choose a number of r-points, n_r, to evaluate the second 
    271285        derivative of P(r) at. This is used as our regularization term. 
    272286        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.