Changeset 6fd4e36 in sasview for src/sas/qtgui/Perspectives


Ignore:
Timestamp:
Mar 28, 2017 8:53:29 AM (8 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:
0268aed
Parents:
a9b568c
Message:

Chi2 display + minor refactoring

Location:
src/sas/qtgui/Perspectives
Files:
7 edited

Legend:

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

    r7248d75d r6fd4e36  
    128128 
    129129        # Assign the new Data1D object-wide 
    130         self._data = new_plot 
     130        #self._data = new_plot 
     131        return new_plot 
    131132 
    132133    def new2DPlot(self, return_data): 
     
    171172                                    data_name + "]" 
    172173 
    173         # Assign the new Data2D object-wide 
    174         self._data = new_plot 
     174        return new_plot 
    175175 
    176176    def computeDataRange(self): 
  • src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py

    ra9b568c r6fd4e36  
    11from PyQt4 import QtGui 
    22from PyQt4 import QtCore 
     3 
     4import numpy 
     5from copy import deepcopy 
     6 
     7from sas.sasgui.guiframe.dataFitting import Data1D 
     8from sas.sasgui.guiframe.dataFitting import Data2D 
    39 
    410def replaceShellName(param_name, value): 
     
    159165            model.appendRow([item1, item2, item3, item4, item5]) 
    160166 
     167def calculateChi2(reference_data, current_data): 
     168    """ 
     169    Calculate Chi2 value between two sets of data 
     170    """ 
     171 
     172    # WEIGHING INPUT 
     173    #from sas.sasgui.perspectives.fitting.utils import get_weight 
     174    #flag = self.get_weight_flag() 
     175    #weight = get_weight(data=self.data, is2d=self._is_2D(), flag=flag) 
     176 
     177    if reference_data == None: 
     178       return chisqr 
     179 
     180    # temporary default values for index and weight 
     181    index = None 
     182    weight = None 
     183 
     184    # Get data: data I, theory I, and data dI in order 
     185    if isinstance(reference_data, Data2D): 
     186        if index == None: 
     187            index = numpy.ones(len(current_data.data), dtype=bool) 
     188        if weight != None: 
     189            current_data.err_data = weight 
     190        # get rid of zero error points 
     191        index = index & (current_data.err_data != 0) 
     192        index = index & (numpy.isfinite(current_data.data)) 
     193        fn = current_data.data[index] 
     194        gn = reference_data.data[index] 
     195        en = current_data.err_data[index] 
     196    else: 
     197        # 1 d theory from model_thread is only in the range of index 
     198        if index == None: 
     199            index = numpy.ones(len(current_data.y), dtype=bool) 
     200        if weight != None: 
     201            current_data.dy = weight 
     202        if current_data.dy == None or current_data.dy == []: 
     203            dy = numpy.ones(len(current_data.y)) 
     204        else: 
     205            ## Set consistently w/AbstractFitengine: 
     206            # But this should be corrected later. 
     207            dy = deepcopy(current_data.dy) 
     208            dy[dy == 0] = 1 
     209        fn = current_data.y[index] 
     210        gn = reference_data.y 
     211        en = dy[index] 
     212    # Calculate the residual 
     213    try: 
     214        res = (fn - gn) / en 
     215    except ValueError: 
     216        print "Chi2 calculations: Unmatched lengths %s, %s, %s" % (len(fn), len(gn), len(en)) 
     217        return 
     218 
     219    residuals = res[numpy.isfinite(res)] 
     220    chisqr = numpy.average(residuals * residuals) 
     221 
     222    return chisqr 
     223 
     224def binary_encode(i, digits): 
     225    return [i >> d & 1 for d in xrange(digits)] 
     226 
  • src/sas/qtgui/Perspectives/Fitting/FittingWidget.py

    ra9b568c r6fd4e36  
    147147        assert isinstance(value[0], QtGui.QStandardItem) 
    148148        # _index contains the QIndex with data 
    149         self._index = value 
     149        self._index = value[0] 
    150150 
    151151        # Update logics with data items 
     
    314314        self.SASModelToQModel(model) 
    315315 
    316         if self._index is None: 
     316        if self.data_is_loaded: 
     317            self.calculateQGridForModel() 
     318        else: 
    317319            # Create default datasets if no data passed 
    318320            self.createDefaultDataset() 
    319         else: 
    320             self.calculateQGridForModel() 
    321321 
    322322    def onSelectStructureFactor(self): 
     
    503503        # multishell params in self.kernel_module.details[??] = value 
    504504 
    505  
    506     def createTheoryIndex(self): 
    507         """ 
    508         Create a QStandardModelIndex containing default model data 
    509         """ 
    510         name = self.kernel_module.name 
     505    def nameForFittedData(self, name): 
     506        """ 
     507        Generate name for the current fit 
     508        """ 
    511509        if self.is2D: 
    512510            name += "2d" 
    513511        name = "M%i [%s]" % (self.tab_id, name) 
    514         new_item = GuiUtils.createModelItemWithPlot(QtCore.QVariant(self.data), name=name) 
    515         # Notify the GUI manager so it can update the theory model in DataExplorer 
     512        return name 
     513 
     514    def createNewIndex(self, fitted_data): 
     515        """ 
     516        Create a model or theory index with passed Data1D/Data2D 
     517        """ 
     518        if self.data_is_loaded: 
     519            self.updateModelIndex(fitted_data) 
     520        else: 
     521            self.createTheoryIndex(fitted_data) 
     522 
     523    def updateModelIndex(self, fitted_data): 
     524        """ 
     525        Update a QStandardModelIndex containing model data 
     526        """ 
     527        name = self.nameForFittedData(self.logic.data.filename) 
     528        fitted_data.title = name 
     529        fitted_data.name = name 
     530        # Make this a line 
     531        fitted_data.symbol = 'Line' 
     532        # Notify the GUI manager so it can update the main model in DataExplorer 
     533        GuiUtils.updateModelItemWithPlot(self._index, QtCore.QVariant(fitted_data), name) 
     534 
     535    def createTheoryIndex(self, fitted_data): 
     536        """ 
     537        Create a QStandardModelIndex containing model data 
     538        """ 
     539        name = self.nameForFittedData(self.kernel_module.name) 
     540        fitted_data.title = name 
     541        fitted_data.name = name 
     542        fitted_data.filename = name 
     543        # Notify the GUI manager so it can create the theory model in DataExplorer 
     544        new_item = GuiUtils.createModelItemWithPlot(QtCore.QVariant(fitted_data), name=name) 
    516545        self.communicate.updateTheoryFromPerspectiveSignal.emit(new_item) 
    517546 
     
    520549        Perform fitting on the current data 
    521550        """ 
     551        # TODO: everything here 
    522552        #self.calculate1DForModel() 
    523553        pass 
     
    527557        Plot the current set of data 
    528558        """ 
    529         # TODO: reimplement basepage.py/_update_paramv_on_fit 
    530         if self.data is None or not self.data.is_data: 
     559        if self.data is None :#or not self.data.is_data: 
    531560            self.createDefaultDataset() 
    532561        self.calculateQGridForModel() 
     
    607636        Plot the current 1D data 
    608637        """ 
    609         self.logic.new1DPlot(return_data) 
    610         self.createTheoryIndex() 
    611  
    612         #output=self._cal_chisqr(data=data, 
     638        fitted_data = self.logic.new1DPlot(return_data) 
     639        self.calculateResiduals(self.logic.new1DPlot(return_data)) 
     640 
     641    def complete2D(self, return_data): 
     642        """ 
     643        Plot the current 2D data 
     644        """ 
     645        fitted_data = self.logic.new2DPlot(return_data) 
     646        self.calculateResiduals(fitted_data) 
     647 
     648    def calculateResiduals(self, fitted_data): 
     649        """ 
     650        Calculate and print Chi2 and display chart of residuals 
     651        """ 
     652        # Create a new index for holding data 
     653        self.createNewIndex(fitted_data) 
     654        # Calculate difference between return_data and logic.data 
     655        chi2 = FittingUtilities.calculateChi2(fitted_data, self.logic.data) 
     656        # Update the control 
     657        self.lblChi2Value.setText(GuiUtils.formatNumber(chi2, high=True)) 
     658 
     659        # TODO: plot residuals 
     660        #self._plot_residuals(page_id=page_id, data=current_data, 
    613661        #                        fid=fid, 
    614         #                        weight=weight, 
    615         #                        page_id=page_id, 
    616         #                        index=index) 
    617  
    618     def complete2D(self, return_data): 
    619         """ 
    620         Plot the current 2D data 
    621         """ 
    622         self.logic.new2DPlot(return_data) 
    623         self.createTheoryIndex() 
    624  
    625         #output=self._cal_chisqr(data=data, 
    626         #                        weight=weight, 
    627         #                        fid=fid, 
    628         #                        page_id=page_id, 
    629         #                        index=index) 
    630         #    self._plot_residuals(page_id=page_id, data=data, fid=fid, 
    631         #                            index=index, weight=weight) 
     662        #                        weight=weight, index=index) 
    632663 
    633664    def calcException(self, etype, value, tb): 
  • src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingLogicTest.py

    r351b53e r6fd4e36  
    104104                        data, False, None) 
    105105 
    106         self.logic.new1DPlot(return_data=return_data) 
     106        new_plot = self.logic.new1DPlot(return_data=return_data) 
    107107 
    108         self.assertIsInstance(self.logic.data, Data1D) 
    109         self.assertFalse(self.logic.data.is_data) 
    110         self.assertEqual(self.logic.data.dy.size, 3) 
    111         self.assertEqual(self.logic.data.title, "boop") 
    112         self.assertEqual(self.logic.data.name, "boop [boop]") 
     108        self.assertIsInstance(new_plot, Data1D) 
     109        self.assertFalse(new_plot.is_data) 
     110        self.assertEqual(new_plot.dy.size, 3) 
     111        self.assertEqual(new_plot.title, "boop") 
     112        self.assertEqual(new_plot.name, "boop [boop]") 
    113113 
    114114    def testNew2DPlot(self): 
     
    142142                        0.1, False, None) 
    143143 
    144         self.logic.new2DPlot(return_data=return_data) 
     144        new_plot = self.logic.new2DPlot(return_data=return_data) 
    145145 
    146         self.assertIsInstance(self.logic.data, Data2D) 
    147         self.assertFalse(self.logic.data.is_data) 
    148         self.assertEqual(self.logic.data.title, "Analytical model 2D ") 
    149         self.assertEqual(self.logic.data.name, "boop [boop]") 
     146        self.assertIsInstance(new_plot, Data2D) 
     147        self.assertFalse(new_plot.is_data) 
     148        self.assertEqual(new_plot.title, "Analytical model 2D ") 
     149        self.assertEqual(new_plot.name, "boop [boop]") 
    150150 
    151151 
  • src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingUtilitiesTest.py

    rb1e36a3 r6fd4e36  
    33from PyQt4 import QtGui 
    44 
     5from sas.sasgui.guiframe.dataFitting import Data1D 
     6from sas.sasgui.guiframe.dataFitting import Data2D 
     7 
    58from UnitTesting.TestUtils import WarningTestNotImplemented 
    6 #from sasmodels.sasview_model import load_standard_models 
     9 
    710from sasmodels import generate 
    811from sasmodels import modelinfo 
     
    180183        self.assertEqual(model.item(1).child(0).child(0,1).text(), "40.0") 
    181184 
     185    def testCalculate1DChi2(self): 
     186        """ 
     187        Test the chi2 calculator for Data1D 
     188        """ 
     189        reference_data = Data1D(x=[0.1, 0.2], y=[0.0, 0.0]) 
     190 
     191        # 1. identical data 
     192        current_data = Data1D(x=[0.1, 0.2], y=[0.0, 0.0]) 
     193 
     194        chi = FittingUtilities.calculateChi2(reference_data, current_data) 
     195 
     196        # Should be zero 
     197        self.assertAlmostEqual(chi, 0.0, 8) 
     198 
     199        # 2. far data 
     200        current_data = Data1D(x=[0.1, 0.2], y=[200.0, 150.0]) 
     201 
     202        chi = FittingUtilities.calculateChi2(reference_data, current_data) 
     203 
     204        # Should not be zero 
     205        self.assertAlmostEqual(chi, 31250.0, 8) 
     206 
     207        # 3. Wrong data 
     208        current_data = Data1D(x=[0.1, 0.2], y=[200.0, 150.0, 200.0]) 
     209        chi = FittingUtilities.calculateChi2(reference_data, current_data) 
     210        # Should be None 
     211        self.assertIsNone(chi) 
     212 
     213    def testCalculate2DChi2(self): 
     214        """ 
     215        Test the chi2 calculator for Data2D 
     216        """ 
     217        reference_data = Data2D(image=[1.0, 2.0, 3.0], 
     218                      err_image=[0.01, 0.02, 0.03], 
     219                      qx_data=[0.1, 0.2, 0.3], 
     220                      qy_data=[0.1, 0.2, 0.3]) 
     221 
     222        # 1. identical data 
     223        current_data = Data2D(image=[1.0, 2.0, 3.0], 
     224                      err_image=[0.01, 0.02, 0.03], 
     225                      qx_data=[0.1, 0.2, 0.3], 
     226                      qy_data=[0.1, 0.2, 0.3]) 
     227 
     228        chi = FittingUtilities.calculateChi2(reference_data, current_data) 
     229 
     230        # Should be zero 
     231        self.assertAlmostEqual(chi, 0.0, 8) 
     232 
     233        # 2. far data 
     234        current_data = Data2D(image=[100.0, 200.0, 300.0], 
     235                      err_image=[1.01, 2.02, 3.03], 
     236                      qx_data=[0.1, 0.2, 0.3], 
     237                      qy_data=[100.0, 200., 300.]) 
     238 
     239        chi = FittingUtilities.calculateChi2(reference_data, current_data) 
     240 
     241        # Should not be zero 
     242        self.assertAlmostEqual(chi, 9607.88, 2) 
     243 
     244        # 3. Wrong data 
     245        current_data = Data2D(image=[1.0, 2.0, 3.0], 
     246                      err_image=[0.01, 0.02], 
     247                      qx_data=[0.1, 0.2], 
     248                      qy_data=[0.1, 0.2, 0.3]) 
     249        # Should throw 
     250        with self.assertRaises(ValueError): 
     251            chi = FittingUtilities.calculateChi2(reference_data, current_data) 
     252 
    182253if __name__ == "__main__": 
    183254    unittest.main() 
  • src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py

    r9934e48 r6fd4e36  
    215215        self.assertFalse(self.widget.calculateQGridForModel.called) 
    216216 
    217         # Let's set a dummy index on widget 
    218         self.widget._index = QtGui.QStandardItem() 
     217        # Let's tell the widget that data has been loaded 
     218        self.widget.data_is_loaded = True 
    219219        # Reset the sasmodel index 
    220220        self.widget.cbModel.setCurrentIndex(1) 
  • src/sas/qtgui/Perspectives/Invariant/InvariantPerspective.py

    rb1e36a3 r6fd4e36  
    5959        self._manager = parent 
    6060        #self._manager = manager 
    61         self._reactor = self._manager.reactor() 
     61        self._reactor = reactor 
    6262        self._model_item = QtGui.QStandardItem() 
    6363 
Note: See TracChangeset for help on using the changeset viewer.