Ignore:
Timestamp:
Oct 27, 2017 11:34:56 AM (7 years ago)
Author:
krzywon
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
Message:

P(r) calculation threads running in Qt GUI.

Location:
src/sas/qtgui/Perspectives/PrInversion
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/Perspectives/PrInversion/PrInversionPerspective.py

    rbde1a6b rdab3351  
     1import sys 
     2import logging 
    13import numpy as np 
    24 
     
    1315# pr inversion calculation elements 
    1416from sas.sascalc.pr.invertor import Invertor 
    15 from sas.sasgui.perspectives.pr import pr_thread as pr_thread 
    1617 
    1718 
     
    5253        # p(r) calculator 
    5354        self._calculator = Invertor() 
     55        self._last_calculator = None 
     56        self.calc_thread = None 
     57        self.estimation_thread = None 
    5458 
    5559        self.model = QtGui.QStandardItemModel(self) 
     
    100104        # self.dataList.currentIndexChanged.connect(self.displayChange) 
    101105        self.calculateButton.clicked.connect(self._calculation) 
    102         self.statusButton.clicked.connect(self.status) 
    103106        self.helpButton.clicked.connect(self.help) 
    104107        self.estimateBgd.toggled.connect(self.toggleBgd) 
    105108        self.manualBgd.toggled.connect(self.toggleBgd) 
     109        self.regConstantSuggestionButton.clicked.connect(self.acceptAlpha) 
     110        self.noOfTermsSuggestionButton.clicked.connect(self.acceptNoTerms) 
    106111        self.explorerButton.clicked.connect(self.openExplorerWindow) 
    107112        self.model.itemChanged.connect(self.model_changed) 
     
    151156        # Main Buttons 
    152157        self.mapper.addMapping(self.calculateButton, WIDGETS.W_CALCULATE) 
    153         self.mapper.addMapping(self.statusButton, WIDGETS.W_STATUS) 
    154158        self.mapper.addMapping(self.helpButton, WIDGETS.W_HELP) 
    155159 
     
    203207        """ 
    204208        if self._has_data: 
    205             self.statusButton.setEnabled(True) 
    206209            self.explorerButton.setEnabled(True) 
    207210            self.calculateButton.setEnabled(True) 
     
    209212            self.calculateButton.setEnabled(False) 
    210213            self.explorerButton.setEnabled(False) 
    211             self.statusButton.setEnabled(False) 
    212214 
    213215    def populateDataComboBox(self, filename): 
     
    219221        self.dataList.addItem(qt_item) 
    220222 
    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 
    223235 
    224236    def _calculation(self): 
     
    226238        Calculate the P(r) for every data set in the data list 
    227239        """ 
    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() 
    230244 
    231245    def model_changed(self): 
     
    235249        self.mapper.toFirst() 
    236250        # TODO: Update plots, etc. 
    237  
    238     def status(self): 
    239         """ 
    240         Show the status of the calculations 
    241         """ 
    242         # TODO: Status - is this even needed/wanted? 
    243         pass 
    244251 
    245252    def help(self): 
     
    314321                               QtGui.QStandardItem(str(data_object.x.max()))) 
    315322 
    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 
    324327 
    325328            # TODO: Only load in the 1st data until batch mode is working 
     329            # TODO: Thus, the break 
    326330            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) 
  • src/sas/qtgui/Perspectives/PrInversion/PrInversionUtils.py

    rbde1a6b rdab3351  
    2828                # bottom buttons 
    2929                'W_CALCULATE', 
    30                 'W_STATUS', 
    3130                'W_HELP' 
    3231) 
  • src/sas/qtgui/Perspectives/PrInversion/UI/TabbedPrInversionUI.ui

    rbde1a6b rdab3351  
    6868     </item> 
    6969     <item> 
    70       <widget class="QPushButton" name="statusButton"> 
    71        <property name="sizePolicy"> 
    72         <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> 
    73          <horstretch>0</horstretch> 
    74          <verstretch>0</verstretch> 
    75         </sizepolicy> 
    76        </property> 
    77        <property name="text"> 
    78         <string>Status</string> 
    79        </property> 
    80       </widget> 
    81      </item> 
    82      <item> 
    8370      <widget class="QPushButton" name="helpButton"> 
    8471       <property name="sizePolicy"> 
Note: See TracChangeset for help on using the changeset viewer.