Changeset 116dd4c1 in sasview for src/sas/qtgui/Perspectives/Fitting


Ignore:
Timestamp:
Jan 24, 2018 10:07:08 AM (7 years ago)
Author:
Piotr Rozyczko <rozyczko@…>
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:
c6343a5
Parents:
eb1a386
Message:

Towards working C&S fits - SASVIEW-846

Location:
src/sas/qtgui/Perspectives/Fitting
Files:
3 edited

Legend:

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

    reb1a386 r116dd4c1  
    22import sys 
    33 
     4from twisted.internet import threads 
     5 
    46import sas.qtgui.Utilities.GuiUtils as GuiUtils 
    57from PyQt5 import QtGui, QtCore, QtWidgets 
    68 
     9from sas.sascalc.fit.BumpsFitting import BumpsFit as Fit 
     10 
    711import sas.qtgui.Utilities.ObjectLibrary as ObjectLibrary 
    8  
    912from sas.qtgui.Perspectives.Fitting.UI.ConstraintWidgetUI import Ui_ConstraintWidgetUI 
    1013from sas.qtgui.Perspectives.Fitting.FittingWidget import FittingWidget 
     14from sas.qtgui.Perspectives.Fitting.FitThread import FitThread 
     15from sas.qtgui.Perspectives.Fitting.ConsoleUpdate import ConsoleUpdate 
    1116from sas.qtgui.Perspectives.Fitting.ComplexConstraint import ComplexConstraint 
    1217from sas.qtgui.Perspectives.Fitting.Constraints import Constraint 
     
    1722    """ 
    1823 
    19     def __init__(self, parent=None): 
     24    def __init__(self, parent=None, tab_id=1): 
    2025        super(ConstraintWidget, self).__init__() 
    2126        self.parent = parent 
    2227        self.setupUi(self) 
    2328        self.currentType = "FitPage" 
     29        self.tab_id = tab_id 
     30        # Page id for fitting 
     31        # To keep with previous SasView values, use 300 as the start offset 
     32        self.page_id = 300 + self.tab_id 
    2433 
    2534        # Remember previous content of modified cell 
     
    114123        Perform the constrained/simultaneous fit 
    115124        """ 
    116         pass 
     125        # Find out all tabs to fit 
     126        tabs_to_fit = [tab for tab in self.tabs_for_fitting if self.tabs_for_fitting[tab]] 
     127 
     128        # Single fitter for the simultaneous run 
     129        sim_fitter = Fit() 
     130        sim_fitter.fitter_id = self.page_id 
     131 
     132        # prepare fitting problems for each tab 
     133        # 
     134        page_ids = [] 
     135        fitter_id = 0 
     136        sim_fitter=[sim_fitter] 
     137        for tab in tabs_to_fit: 
     138            tab_object = ObjectLibrary.getObject(tab) 
     139            sim_fitter, fitter_id = tab_object.prepareFitters(fitter=sim_fitter[0], fit_id=fitter_id) 
     140            page_ids.append([tab_object.page_id]) 
     141 
     142        # Create the fitting thread, based on the fitter 
     143        completefn = self.onBatchFitComplete if self.currentType=='BatchPage' else self.onFitComplete 
     144 
     145        #if USING_TWISTED: 
     146        handler = None 
     147        updater = None 
     148        #else: 
     149        #    handler = ConsoleUpdate(parent=self.parent, 
     150        #                            manager=self, 
     151        #                            improvement_delta=0.1) 
     152        #    updater = handler.update_fit 
     153 
     154        batch_inputs = {} 
     155        batch_outputs = {} 
     156 
     157        # new fit thread object 
     158        calc_fit = FitThread(handler=handler, 
     159                             fn=sim_fitter, 
     160                             batch_inputs=batch_inputs, 
     161                             batch_outputs=batch_outputs, 
     162                             page_id=page_ids, 
     163                             updatefn=updater, 
     164                             completefn=completefn) 
     165 
     166        #if USING_TWISTED: 
     167        # start the trhrhread with twisted 
     168        calc_thread = threads.deferToThread(calc_fit.compute) 
     169        calc_thread.addCallback(self.onFitComplete) 
     170        calc_thread.addErrback(self.onFitFailed) 
     171        #else: 
     172        #    # Use the old python threads + Queue 
     173        #    calc_fit.queue() 
     174        #    calc_fit.ready(2.5) 
     175 
     176 
     177        #disable the Fit button 
     178        self.cmdFit.setText('Running...') 
     179        self.parent.communicate.statusBarUpdateSignal.emit('Fitting started...') 
     180        self.cmdFit.setEnabled(False) 
    117181 
    118182    def onHelp(self): 
     
    172236    def onConstraintChange(self, row, column): 
    173237        """ 
    174         Modify the constraint in-place. 
     238        Modify the constraint's "active" instance variable. 
    175239        """ 
    176240        item = self.tblConstraints.item(row, column) 
     
    208272        pass 
    209273 
     274    def onFitComplete(self, result): 
     275        """ 
     276        Respond to the successful fit complete signal 
     277        """ 
     278        pass 
     279 
     280    def onBatchFitComplete(self, result): 
     281        """ 
     282        Respond to the successful batch fit complete signal 
     283        """ 
     284        pass 
     285 
     286    def onFitFailed(self, reason): 
     287        """ 
     288        """ 
     289        print("FIT FAILED: ", reason) 
     290        pass 
     291  
    210292    def isTabImportable(self, tab): 
    211293        """ 
  • src/sas/qtgui/Perspectives/Fitting/FittingPerspective.py

    rbe8f4b0 r116dd4c1  
    124124        Add a new C&S fitting tab 
    125125        """ 
    126         tab     = ConstraintWidget(parent=self) 
     126        tab     = ConstraintWidget(parent=self, tab_id=self.maxCSIndex) 
    127127        # Add this tab to the object library so it can be retrieved by scripting/jupyter 
    128128        tab_name = self.getCSTabName() # TODO update the tab name scheme 
  • src/sas/qtgui/Perspectives/Fitting/FittingWidget.py

    rba01ad1 r116dd4c1  
    212212        self.orig_poly_index = 3 
    213213 
     214        # Page id for fitting 
     215        # To keep with previous SasView values, use 200 as the start offset 
     216        self.page_id = 200 + self.tab_id 
     217 
    214218        # Data for chosen model 
    215219        self.model_data = None 
     
    732736                return True 
    733737        return False 
    734         #return True if (item.hasChildren() and isinstance(item.child(0).data(), Constraint)) else False 
     738 
     739    def rowHasActiveConstraint(self, row): 
     740        """ 
     741        Finds out if row of the main model has an active constraint child 
     742        """ 
     743        item = self._model_model.item(row,1) 
     744        if item.hasChildren(): 
     745            c = item.child(0).data() 
     746            if isinstance(c, Constraint) and c.func and c.active: 
     747                return True 
     748        return False 
    735749 
    736750    def selectParameters(self): 
     
    780794                    #preamble(s) +self._model_model.item(s, 1).child(0).data().func) 
    781795                    self._model_model.item(s, 1).child(0).data().func) 
    782                     for s in range(param_number) if self.rowHasConstraint(s)] 
     796                    for s in range(param_number) if self.rowHasActiveConstraint(s)] 
    783797        return params 
    784798 
     
    10561070        Perform fitting on the current data 
    10571071        """ 
    1058  
    1059         # Data going in 
    1060         data = self.logic.data 
    1061         model = self.kernel_module 
    1062         qmin = self.q_range_min 
    1063         qmax = self.q_range_max 
    1064         params_to_fit = self.parameters_to_fit 
    1065  
    1066         # Potential weights added directly to data 
    1067         self.addWeightingToData(data) 
    1068  
    1069         # Potential smearing added 
    1070         # Remember that smearing_min/max can be None -> 
    1071         # deal with it until Python gets discriminated unions 
    1072         smearing, accuracy, smearing_min, smearing_max = self.smearing_widget.state() 
    1073  
    1074         # These should be updating somehow? 
     1072        # initialize fitter constants 
    10751073        fit_id = 0 
    1076         constraints = self.getConstraintsForModel() 
    1077         smearer = None 
    1078         page_id = [210] 
    10791074        handler = None 
    10801075        batch_inputs = {} 
    10811076        batch_outputs = {} 
    1082         list_page_id = [page_id] 
    10831077        #--------------------------------- 
    10841078        if USING_TWISTED: 
     
    10911085            updater = handler.update_fit 
    10921086 
    1093         # Parameterize the fitter 
    1094         fitters = [] 
    1095         for fit_index in self.all_data: 
    1096             fitter = Fit() 
    1097             data = GuiUtils.dataFromItem(fit_index) 
    1098             try: 
    1099                 fitter.set_model(model, fit_id, params_to_fit, data=data, 
    1100                              constraints=constraints) 
    1101             except ValueError as ex: 
    1102                 logging.error("Setting model parameters failed with: %s" % ex) 
    1103                 return 
    1104  
    1105             qmin, qmax, _ = self.logic.computeRangeFromData(data) 
    1106             fitter.set_data(data=data, id=fit_id, smearer=smearer, qmin=qmin, 
    1107                             qmax=qmax) 
    1108             fitter.select_problem_for_fit(id=fit_id, value=1) 
    1109             fitter.fitter_id = page_id 
    1110             fit_id += 1 
    1111             fitters.append(fitter) 
     1087        # Prepare the fitter object 
     1088        fitters, _ = self.prepareFitters() 
    11121089 
    11131090        # Create the fitting thread, based on the fitter 
     
    11151092 
    11161093        calc_fit = FitThread(handler=handler, 
    1117                                 fn=fitters, 
    1118                                 batch_inputs=batch_inputs, 
    1119                                 batch_outputs=batch_outputs, 
    1120                                 page_id=list_page_id, 
    1121                                 updatefn=updater, 
    1122                                 completefn=completefn) 
     1094                            fn=fitters, 
     1095                            batch_inputs=batch_inputs, 
     1096                            batch_outputs=batch_outputs, 
     1097                            page_id=[[self.page_id]], 
     1098                            updatefn=updater, 
     1099                            completefn=completefn) 
    11231100 
    11241101        if USING_TWISTED: 
     
    12091186        chi2_repr = GuiUtils.formatNumber(self.chi2, high=True) 
    12101187        self.lblChi2Value.setText(chi2_repr) 
     1188 
     1189    def prepareFitters(self, fitter=None, fit_id=0): 
     1190        """ 
     1191        Prepare the Fitter object for use in fitting 
     1192        """ 
     1193        # fitter = None -> single/batch fitting 
     1194        # fitter = Fit() -> simultaneous fitting 
     1195 
     1196        # Data going in 
     1197        data = self.logic.data 
     1198        model = self.kernel_module 
     1199        qmin = self.q_range_min 
     1200        qmax = self.q_range_max 
     1201        params_to_fit = self.parameters_to_fit 
     1202 
     1203        # Potential weights added directly to data 
     1204        self.addWeightingToData(data) 
     1205 
     1206        # Potential smearing added 
     1207        # Remember that smearing_min/max can be None -> 
     1208        # deal with it until Python gets discriminated unions 
     1209        smearing, accuracy, smearing_min, smearing_max = self.smearing_widget.state() 
     1210 
     1211        constraints = self.getConstraintsForModel() 
     1212        smearer = None 
     1213        handler = None 
     1214        batch_inputs = {} 
     1215        batch_outputs = {} 
     1216 
     1217        fitters = [] 
     1218        for fit_index in self.all_data: 
     1219            fitter_single = Fit() if fitter is None else fitter 
     1220            data = GuiUtils.dataFromItem(fit_index) 
     1221            try: 
     1222                fitter_single.set_model(model, fit_id, params_to_fit, data=data, 
     1223                             constraints=constraints) 
     1224            except ValueError as ex: 
     1225                logging.error("Setting model parameters failed with: %s" % ex) 
     1226                return 
     1227 
     1228            qmin, qmax, _ = self.logic.computeRangeFromData(data) 
     1229            fitter_single.set_data(data=data, id=fit_id, smearer=smearer, qmin=qmin, 
     1230                            qmax=qmax) 
     1231            fitter_single.select_problem_for_fit(id=fit_id, value=1) 
     1232            if fitter is None: 
     1233                # Assign id to the new fitter only 
     1234                fitter_single.fitter_id = [self.page_id] 
     1235            fit_id += 1 
     1236            fitters.append(fitter_single) 
     1237 
     1238        return fitters, fit_id 
    12111239 
    12121240    def iterateOverModel(self, func): 
Note: See TracChangeset for help on using the changeset viewer.