Changeset 1042dba in sasview for src/sas/qtgui


Ignore:
Timestamp:
Jun 17, 2016 9:56:01 AM (8 years ago)
Author:
Piotr Rozyczko <piotr.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:
9e426c1
Parents:
a281ab8
Message:

Plottables support in the data object. Additional menu items.

Location:
src/sas/qtgui
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/DataExplorer.py

    ra281ab8 r1042dba  
    1111# SAS 
    1212from GuiUtils import * 
     13from Plotter import Plotter 
    1314from sas.sascalc.dataloader.loader import Loader 
    1415from sas.sasgui.guiframe.data_manager import DataManager 
     
    4142        self.cmdDelete.clicked.connect(self.deleteFile) 
    4243        self.cmdSendTo.clicked.connect(self.sendData) 
     44        self.cmdNew.clicked.connect(self.newPlot) 
    4345 
    4446        # Connect the comboboxes 
     
    5456        # The Data viewer is QTreeView showing the proxy model 
    5557        self.treeView.setModel(self.proxy) 
     58 
     59        # Debug view on the model 
     60        self.listView.setModel(self.model) 
    5661 
    5762 
     
    163168        self._perspective.setData(data_item=data) 
    164169 
     170    def newPlot(self): 
     171        """ 
     172        Create a new matplotlib chart from selected data 
     173        """ 
     174 
     175        plots = plotsFromCheckedItems(self.model) 
     176 
     177        # Call show on requested plots 
     178        new_plot = Plotter() 
     179        for plot_set in plots: 
     180            new_plot.data(plot_set) 
     181            new_plot.plot() 
     182 
     183        new_plot.show() 
    165184 
    166185    def chooseFiles(self): 
     
    415434 
    416435        # Add "Info" item 
    417         info_item = QtGui.QStandardItem("Info") 
     436        # info_item = QtGui.QStandardItem("Info") 
    418437 
    419438        # Add the actual Data1D/Data2D object 
     
    424443 
    425444        # Add rows for display in the view 
    426         self.addExtraRows(info_item, data) 
     445        # self.addExtraRows(info_item, data) 
     446        info_item = infoFromData(data) 
    427447 
    428448        # Set info_item as the only child 
     
    444464            msg = "Wrong data type returned from calculations." 
    445465            raise AttributeError, msg 
    446         # Assert other properties 
    447  
    448         # Remove the original item         
    449  
    450         # Add the current item 
    451         # self.model.insertRow(model_item) 
     466 
     467        # TODO: Assert other properties 
    452468 
    453469        # Reset the view 
    454470        self.model.reset() 
     471 
    455472        # Pass acting as a debugger anchor 
    456473        pass 
    457  
    458     def addExtraRows(self, info_item, data): 
    459         """ 
    460         Extract relevant data to include in the Info ModelItem 
    461         """ 
    462         title_item   = QtGui.QStandardItem("Title: "      + data.title) 
    463         run_item     = QtGui.QStandardItem("Run: "        + str(data.run)) 
    464         type_item    = QtGui.QStandardItem("Type: "       + str(data.__class__.__name__)) 
    465         path_item    = QtGui.QStandardItem("Path: "       + data.path) 
    466         instr_item   = QtGui.QStandardItem("Instrument: " + data.instrument) 
    467         process_item = QtGui.QStandardItem("Process") 
    468         if isinstance(data.process, list) and data.process: 
    469             for process in data.process: 
    470                 process_date = process.date 
    471                 process_date_item = QtGui.QStandardItem("Date: " + process_date) 
    472                 process_item.appendRow(process_date_item) 
    473  
    474                 process_descr = process.description 
    475                 process_descr_item = QtGui.QStandardItem("Description: " + process_descr) 
    476                 process_item.appendRow(process_descr_item) 
    477  
    478                 process_name = process.name 
    479                 process_name_item = QtGui.QStandardItem("Name: " + process_name) 
    480                 process_item.appendRow(process_name_item) 
    481  
    482         info_item.appendRow(title_item) 
    483         info_item.appendRow(run_item) 
    484         info_item.appendRow(type_item) 
    485         info_item.appendRow(path_item) 
    486         info_item.appendRow(instr_item) 
    487         info_item.appendRow(process_item) 
    488474        
    489475 
  • src/sas/qtgui/GuiManager.py

    r5032ea68 r1042dba  
    33from PyQt4 import QtCore 
    44from PyQt4 import QtGui 
     5from PyQt4 import QtWebKit 
     6 
     7from twisted.internet import reactor 
    58 
    69# General SAS imports 
     10from sas.sasgui.guiframe.data_manager import DataManager 
    711import LocalConfig 
    812from GuiUtils import * 
     
    3135 
    3236        # Create the data manager 
    33         #self._data_manager = DataManager() 
     37        # TODO: pull out all required methods from DataManager and reimplement 
     38        self._data_manager = DataManager() 
    3439 
    3540        # Create action triggers 
     
    5560        self.welcomePanel = WelcomePanel() 
    5661        self._workspace.workspace.addWindow(self.welcomePanel) 
     62 
     63        # Current help file 
     64        self._helpView = QtWebKit.QWebView() 
     65        self._helpLocation = "html/index.html" 
    5766 
    5867        #========================================================== 
     
    107116        self._workspace.statusbar.showMessage(text) 
    108117 
    109     #def createGuiData(self, item, p_file): 
    110     #    """ 
    111     #    """ 
    112     #    return self._data_manager.create_gui_data(item, p_file) 
     118    def createGuiData(self, item, p_file=None): 
     119        """ 
     120        Access the Data1D -> plottable Data1D conversion 
     121        """ 
     122        return self._data_manager.create_gui_data(item, p_file) 
    113123 
    114124    def addData(self, data_list): 
     
    255265        """ 
    256266        print("actionSave_Analysis TRIGGERED") 
     267        
    257268        pass 
    258269 
    259270    def actionQuit(self): 
    260271        """ 
    261         """ 
    262         print("actionQuit TRIGGERED") 
    263         pass 
     272        Close the reactor, exit the application. 
     273        """ 
     274        # display messagebox 
     275        quit_msg = "Are you sure you want to exit the application?" 
     276        reply = QtGui.QMessageBox.question(self._parent, 'Warning', quit_msg, 
     277                QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) 
     278 
     279        if reply == QtGui.QMessageBox.No: 
     280            return 
     281 
     282        # exit if yes 
     283        reactor.callFromThread(reactor.stop) 
     284        sys.exit() 
    264285 
    265286    #============ EDIT ================= 
     
    489510        """ 
    490511        """ 
    491         print("actionDocumentation TRIGGERED") 
    492         pass 
     512        self._helpView.load(QtCore.QUrl(self._helpLocation)) 
     513        self._helpView.show() 
    493514 
    494515    def actionTutorial(self): 
  • src/sas/qtgui/GuiUtils.py

    ra281ab8 r1042dba  
    2626#from sas.sasgui.guiframe.events import NewPlotEvent 
    2727from sas.sasgui.guiframe.dataFitting import Data1D 
     28from sas.sasgui.guiframe.dataFitting import Data2D 
    2829 
    2930 
     
    209210def updateModelItem(item, update_data, name=""): 
    210211    """ 
    211     Updates QStandardItem with a checkboxed row named 'name' 
    212     and containing QVariant 'update_data' 
     212    Adds a checkboxed row named "name" to QStandardItem 
     213    Adds QVariant 'update_data' to that row. 
    213214    """ 
    214215    assert type(item) == QtGui.QStandardItem 
     
    221222 
    222223    # Add "Info" item 
    223     info_item = QtGui.QStandardItem("Info") 
     224    py_update_data = update_data.toPyObject() 
     225    if type(py_update_data) == (Data1D or Data2D): 
     226        # If Data1/2D added - extract Info from it 
     227        info_item = infoFromData(py_update_data) 
     228    else: 
     229        # otherwise just add a naked item 
     230        info_item = QtGui.QStandardItem("Info")         
    224231 
    225232    # Add the actual Data1D/Data2D object 
     
    227234    object_item.setData(update_data) 
    228235 
     236    # Set the data object as the first child 
    229237    checkbox_item.setChild(0, object_item) 
    230238 
    231     # Set info_item as the only child 
     239    # Set info_item as the second child 
    232240    checkbox_item.setChild(1, info_item) 
    233241 
    234242    # Append the new row to the main item 
    235243    item.appendRow(checkbox_item) 
     244 
     245def plotsFromCheckedItems(model_item): 
     246    """ 
     247    Returns the list of plots for items in the model which are checked 
     248    """ 
     249    assert type(model_item) == QtGui.QStandardItemModel 
     250 
     251    checkbox_item = QtGui.QStandardItem(True) 
     252    plot_data = [] 
     253 
     254    # Iterate over model looking for items with checkboxes 
     255    for index in range(model_item.rowCount()): 
     256        item = model_item.item(index) 
     257        if item.isCheckable() and item.checkState() == QtCore.Qt.Checked: 
     258            # TODO: assure item type is correct (either data1/2D or Plotter) 
     259            plot_data.append(item.child(0).data().toPyObject()) 
     260        # Going 1 level deeper only 
     261        for index_2 in range(item.rowCount()): 
     262            item_2 = item.child(index_2) 
     263            if item_2 and item_2.isCheckable() and item_2.checkState() == QtCore.Qt.Checked: 
     264                # TODO: assure item type is correct (either data1/2D or Plotter) 
     265                plot_data.append(item_2.child(0).data().toPyObject()) 
     266   
     267    return plot_data 
     268 
     269def infoFromData(data): 
     270    """ 
     271    Given Data1D/Data2D object, extract relevant Info elements 
     272    and add them to a model item 
     273    """ 
     274    assert type(data) in [Data1D, Data2D] 
     275 
     276    info_item = QtGui.QStandardItem("Info") 
     277 
     278    title_item   = QtGui.QStandardItem("Title: "      + data.title) 
     279    info_item.appendRow(title_item) 
     280    run_item     = QtGui.QStandardItem("Run: "        + str(data.run)) 
     281    info_item.appendRow(run_item) 
     282    type_item    = QtGui.QStandardItem("Type: "       + str(data.__class__.__name__)) 
     283    info_item.appendRow(type_item) 
     284 
     285    if data.path: 
     286        path_item    = QtGui.QStandardItem("Path: "       + data.path) 
     287        info_item.appendRow(path_item) 
     288 
     289    if data.instrument: 
     290        instr_item   = QtGui.QStandardItem("Instrument: " + data.instrument) 
     291        info_item.appendRow(instr_item) 
     292 
     293    process_item = QtGui.QStandardItem("Process") 
     294    if isinstance(data.process, list) and data.process: 
     295        for process in data.process: 
     296            process_date = process.date 
     297            process_date_item = QtGui.QStandardItem("Date: " + process_date) 
     298            process_item.appendRow(process_date_item) 
     299 
     300            process_descr = process.description 
     301            process_descr_item = QtGui.QStandardItem("Description: " + process_descr) 
     302            process_item.appendRow(process_descr_item) 
     303 
     304            process_name = process.name 
     305            process_name_item = QtGui.QStandardItem("Name: " + process_name) 
     306            process_item.appendRow(process_name_item) 
     307 
     308    info_item.appendRow(process_item) 
     309 
     310    return info_item 
     311 
  • src/sas/qtgui/Perspectives/Invariant/InvariantPerspective.py

    ra281ab8 r1042dba  
    77 
    88from twisted.internet import threads 
     9from twisted.internet import reactor 
    910 
    1011# sas-global 
    1112from sas.sascalc.invariant import invariant 
    1213from sas.sasgui.guiframe.dataFitting import Data1D 
    13 from sas.qtgui.GuiUtils import Communicate 
    14 from sas.qtgui.GuiUtils import updateModelItem 
     14# from sas.qtgui.GuiUtils import * 
     15from GuiUtils import * 
    1516 
    1617# local 
     
    262263            self._plotter.plot() 
    263264 
     265            # Convert the data into plottable 
     266            extrapolated_data = self._manager.createGuiData(extrapolated_data) 
     267 
    264268            # Add the plot to the model item 
    265             variant_item = QtCore.QVariant(self._plotter) 
    266             updateModelItem(self._model_item, variant_item, title) 
     269            # variant_item = QtCore.QVariant(self._plotter) 
     270            variant_item = QtCore.QVariant(extrapolated_data) 
     271 
     272            # This needs to run in the main thread 
     273            reactor.callFromThread(updateModelItem, self._model_item, variant_item, title) 
    267274 
    268275        if self._high_extrapolate: 
     
    275282            high_out_data = inv.get_extra_data_high(q_end=qmax_plot, npts=500) 
    276283 
     284            # Convert the data into plottable 
     285            high_out_data = self._manager.createGuiData(high_out_data) 
     286 
    277287            # find how to add this plot to the existing plot for low_extrapolate 
    278288            # Plot the chart 
     
    283293 
    284294            # Add the plot to the model item 
    285             variant_item = QtCore.QVariant(self._plotter) 
    286             updateModelItem(self._model_item, variant_item, title) 
    287  
     295            # variant_item = QtCore.QVariant(self._plotter) 
     296            variant_item = QtCore.QVariant(high_out_data) 
     297            # This needs to run in the main thread 
     298            reactor.callFromThread(updateModelItem, self._model_item, variant_item, title) 
    288299 
    289300        item = QtGui.QStandardItem(str(float('%.5g'% volume_fraction))) 
  • src/sas/qtgui/Plotter.py

    rf721030 r1042dba  
    7979        """ 
    8080        # create an axis 
    81         #ax = self.figure.add_subplot(self._current_plot) 
    8281        ax = self._ax 
    83  
    84         # discards the old graph 
    85         # ax.hold(False) 
    8682 
    8783        # plot data with legend 
  • src/sas/qtgui/UnitTesting/DataExplorerTest.py

    ra281ab8 r1042dba  
    99# Local 
    1010from sas.sasgui.guiframe.dataFitting import Data1D 
     11from sas.sascalc.dataloader.loader import Loader 
     12from sas.sasgui.guiframe.data_manager import DataManager 
     13 
    1114from DataExplorer import DataExplorerWindow 
    1215from GuiManager import GuiManager 
    1316from GuiUtils import * 
    1417from UnitTesting.TestUtils import QtSignalSpy 
     18from Plotter import Plotter 
    1519 
    1620app = QApplication(sys.argv) 
     
    297301        self.assertTrue(self.form.manager.add_data.called) 
    298302 
     303    def testNewPlot(self): 
     304        """ 
     305        Creating new plots from Data1D/2D 
     306        """ 
     307        loader = Loader() 
     308        manager = DataManager() 
     309 
     310        # get Data1D 
     311        p_file="cyl_400_20.txt" 
     312        output_object = loader.load(p_file) 
     313        new_data = [manager.create_gui_data(output_object, p_file)] 
     314 
     315        # Mask the plot show call 
     316        Plotter.show = MagicMock() 
     317 
     318        # Mask retrieval of the data 
     319        self.form.plotsFromCheckedItems = MagicMock(return_value=new_data) 
     320 
     321        # Call the plotting method 
     322        self.form.newPlot() 
     323 
     324        # The plot was displayed 
     325        self.assertTrue(Plotter.show.called) 
     326 
    299327 
    300328if __name__ == "__main__": 
  • src/sas/qtgui/UnitTesting/GuiUtilsTest.py

    ra281ab8 r1042dba  
    11import sys 
    22import unittest 
     3 
     4from PyQt4 import QtCore 
     5from PyQt4 import QtGui 
     6 
     7# SV imports 
     8from sas.sascalc.dataloader.loader import Loader 
     9from sas.sasgui.guiframe.data_manager import DataManager 
    310 
    411# Tested module 
     
    1219 
    1320    def tearDown(self): 
    14         '''empty''' 
     21        '''Empty''' 
    1522        pass 
    1623 
     
    7683        self.assertEqual(str(list_from_item[1]), test_list[1]) 
    7784 
     85 
     86    def testPlotsFromCheckedItems(self): 
     87        """ 
     88        Test addition of a plottable to the model 
     89        """ 
     90 
     91        # Mockup data 
     92        test_list0 = "FRIDAY" 
     93        test_list1 = "SATURDAY" 
     94        test_list2 = "MONDAY" 
     95 
     96        # Main item ("file") 
     97        checkbox_model = QtGui.QStandardItemModel() 
     98        checkbox_item = QtGui.QStandardItem(True) 
     99        checkbox_item.setCheckable(True) 
     100        checkbox_item.setCheckState(QtCore.Qt.Checked) 
     101        test_item0 = QtGui.QStandardItem() 
     102        test_item0.setData(QtCore.QVariant(test_list0)) 
     103 
     104        # Checked item 1 
     105        test_item1 = QtGui.QStandardItem(True) 
     106        test_item1.setCheckable(True) 
     107        test_item1.setCheckState(QtCore.Qt.Checked) 
     108        object_item = QtGui.QStandardItem() 
     109        object_item.setData(QtCore.QVariant(test_list1)) 
     110        test_item1.setChild(0, object_item) 
     111 
     112        checkbox_item.setChild(0, test_item0) 
     113        checkbox_item.appendRow(test_item1) 
     114 
     115        # Unchecked item 2 
     116        test_item2 = QtGui.QStandardItem(True) 
     117        test_item2.setCheckable(True) 
     118        test_item2.setCheckState(QtCore.Qt.Unchecked) 
     119        object_item = QtGui.QStandardItem() 
     120        object_item.setData(QtCore.QVariant(test_list2)) 
     121        test_item2.setChild(0, object_item) 
     122        checkbox_item.appendRow(test_item2) 
     123 
     124        checkbox_model.appendRow(checkbox_item) 
     125 
     126        # Pull out the "plottable" documents 
     127        plot_list = plotsFromCheckedItems(checkbox_model) 
     128 
     129        # Make sure only the checked data is present 
     130        # FRIDAY IN 
     131        self.assertIn(test_list0, plot_list) 
     132        # SATURDAY IN 
     133        self.assertIn(test_list1, plot_list) 
     134        # MONDAY NOT IN 
     135        self.assertNotIn(test_list2, plot_list) 
     136 
     137    def testInfoFromData(self): 
     138        """ 
     139        Test Info element extraction from a plottable object 
     140        """ 
     141        loader = Loader() 
     142        manager = DataManager() 
     143 
     144        # get Data1D 
     145        p_file="cyl_400_20.txt" 
     146        output_object = loader.load(p_file) 
     147        new_data = manager.create_gui_data(output_object, p_file) 
     148 
     149        # Extract Info elements into a model item 
     150        item = infoFromData(new_data) 
     151 
     152        # Test the item and its children 
     153        self.assertIsInstance(item, QtGui.QStandardItem) 
     154        self.assertEqual(item.rowCount(), 5) 
     155        self.assertEqual(item.text(), "Info") 
     156        self.assertIn(p_file,   item.child(0).text()) 
     157        self.assertIn("Run",    item.child(1).text()) 
     158        self.assertIn("Data1D", item.child(2).text()) 
     159        self.assertIn(p_file,   item.child(3).text()) 
     160        self.assertIn("Process",item.child(4).text()) 
     161 
     162 
    78163if __name__ == "__main__": 
    79164    unittest.main() 
Note: See TracChangeset for help on using the changeset viewer.