Ignore:
File:
1 edited

Legend:

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

    r9463ca2 rfd7ef36  
    44import time 
    55import logging 
    6 import re 
    76 
    87from PyQt5 import QtCore 
     
    3736    # The controller which is responsible for managing signal slots connections 
    3837    # for the gui and providing an interface to the data model. 
    39  
    40     # This matches the ID of a plot created using FittingLogic._create1DPlot, e.g. 
    41     # "5 [P(Q)] modelname" 
    42     # or 
    43     # "4 modelname". 
    44     # Useful for determining whether the plot in question is for an intermediate result, such as P(Q) or S(Q) in the 
    45     # case of a product model; the identifier for this is held in square brackets, as in the example above. 
    46     theory_plot_ID_pattern = re.compile(r"^([0-9]+)\s+(\[(.*)\]\s+)?(.*)$") 
    4738 
    4839    def __init__(self, parent=None, guimanager=None, manager=None): 
     
    394385        # Notify the GuiManager about the send request 
    395386        self._perspective().setData(data_item=selected_items, is_batch=self.chkBatch.isChecked()) 
     387 
     388    def freezeCheckedData(self): 
     389        """ 
     390        Convert checked results (fitted model, residuals) into separate dataset. 
     391        """ 
     392        outer_index = -1 
     393        theories_copied = 0 
     394        orig_model_size = self.model.rowCount() 
     395        while outer_index < orig_model_size: 
     396            outer_index += 1 
     397            outer_item = self.model.item(outer_index) 
     398            if not outer_item: 
     399                continue 
     400            if not outer_item.isCheckable(): 
     401                continue 
     402            # Look for checked inner items 
     403            inner_index = -1 
     404            while inner_index < outer_item.rowCount(): 
     405               inner_item = outer_item.child(inner_index) 
     406               inner_index += 1 
     407               if not inner_item: 
     408                   continue 
     409               if not inner_item.isCheckable(): 
     410                   continue 
     411               if inner_item.checkState() != QtCore.Qt.Checked: 
     412                   continue 
     413               self.model.beginResetModel() 
     414               theories_copied += 1 
     415               new_item = self.cloneTheory(inner_item) 
     416               self.model.appendRow(new_item) 
     417               self.model.endResetModel() 
     418 
     419        freeze_msg = "" 
     420        if theories_copied == 0: 
     421            return 
     422        elif theories_copied == 1: 
     423            freeze_msg = "1 theory copied to a separate data set" 
     424        elif theories_copied > 1: 
     425            freeze_msg = "%i theories copied to separate data sets" % theories_copied 
     426        else: 
     427            freeze_msg = "Unexpected number of theories copied: %i" % theories_copied 
     428            raise AttributeError(freeze_msg) 
     429        self.communicator.statusBarUpdateSignal.emit(freeze_msg) 
    396430 
    397431    def freezeTheory(self, event): 
     
    538572            else: 
    539573                # Don't plot intermediate results, e.g. P(Q), S(Q) 
    540                 match = self.theory_plot_ID_pattern.match(plot_id) 
     574                match = GuiUtils.theory_plot_ID_pattern.match(plot_id) 
    541575                # 2nd match group contains the identifier for the intermediate result, if present (e.g. "[P(Q)]") 
    542576                if match and match.groups()[1] != None: 
     
    544578                # 'sophisticated' test to generate standalone plot for residuals 
    545579                if 'esiduals' in plot.title: 
    546                     self.plotData([(item, plot)], transform=False) 
     580                    plot.yscale='linear' 
     581                    self.plotData([(item, plot)]) 
    547582                else: 
    548583                    new_plots.append((item, plot)) 
     
    825860        return wlist 
    826861 
     862    def setItemsCheckability(self, model, dimension=None, checked=False): 
     863        """ 
     864        For a given model, check or uncheck all items of given dimension 
     865        """ 
     866        mode = QtCore.Qt.Checked if checked else QtCore.Qt.Unchecked 
     867 
     868        assert isinstance(checked, bool) 
     869 
     870        types = (None, Data1D, Data2D) 
     871        assert dimension in types 
     872 
     873        for index in range(model.rowCount()): 
     874            item = model.item(index) 
     875            if dimension is not None and not isinstance(GuiUtils.dataFromItem(item), dimension): 
     876                continue 
     877            if item.isCheckable() and item.checkState() != mode: 
     878                item.setCheckState(mode) 
     879            # look for all children 
     880            for inner_index in range(item.rowCount()): 
     881                child = item.child(inner_index) 
     882                if child.isCheckable() and child.checkState() != mode: 
     883                    child.setCheckState(mode) 
     884 
    827885    def selectData(self, index): 
    828886        """ 
     
    835893        # Respond appropriately 
    836894        if index == 0: 
    837             # Select All 
    838             for index in range(self.model.rowCount()): 
    839                 item = self.model.item(index) 
    840                 if item.isCheckable() and item.checkState() == QtCore.Qt.Unchecked: 
    841                     item.setCheckState(QtCore.Qt.Checked) 
     895            self.setItemsCheckability(self.model, checked=True) 
     896 
    842897        elif index == 1: 
    843898            # De-select All 
    844             for index in range(self.model.rowCount()): 
    845                 item = self.model.item(index) 
    846                 if item.isCheckable() and item.checkState() == QtCore.Qt.Checked: 
    847                     item.setCheckState(QtCore.Qt.Unchecked) 
     899            self.setItemsCheckability(self.model, checked=False) 
    848900 
    849901        elif index == 2: 
    850902            # Select All 1-D 
    851             for index in range(self.model.rowCount()): 
    852                 item = self.model.item(index) 
    853                 item.setCheckState(QtCore.Qt.Unchecked) 
    854  
    855                 try: 
    856                     is1D = isinstance(GuiUtils.dataFromItem(item), Data1D) 
    857                 except AttributeError: 
    858                     msg = "Bad structure of the data model." 
    859                     raise RuntimeError(msg) 
    860  
    861                 if is1D: 
    862                     item.setCheckState(QtCore.Qt.Checked) 
     903            self.setItemsCheckability(self.model, dimension=Data1D, checked=True) 
    863904 
    864905        elif index == 3: 
    865906            # Unselect All 1-D 
    866             for index in range(self.model.rowCount()): 
    867                 item = self.model.item(index) 
    868  
    869                 try: 
    870                     is1D = isinstance(GuiUtils.dataFromItem(item), Data1D) 
    871                 except AttributeError: 
    872                     msg = "Bad structure of the data model." 
    873                     raise RuntimeError(msg) 
    874  
    875                 if item.isCheckable() and item.checkState() == QtCore.Qt.Checked and is1D: 
    876                     item.setCheckState(QtCore.Qt.Unchecked) 
     907            self.setItemsCheckability(self.model, dimension=Data1D, checked=False) 
    877908 
    878909        elif index == 4: 
    879910            # Select All 2-D 
    880             for index in range(self.model.rowCount()): 
    881                 item = self.model.item(index) 
    882                 item.setCheckState(QtCore.Qt.Unchecked) 
    883                 try: 
    884                     is2D = isinstance(GuiUtils.dataFromItem(item), Data2D) 
    885                 except AttributeError: 
    886                     msg = "Bad structure of the data model." 
    887                     raise RuntimeError(msg) 
    888  
    889                 if is2D: 
    890                     item.setCheckState(QtCore.Qt.Checked) 
     911            self.setItemsCheckability(self.model, dimension=Data2D, checked=True) 
    891912 
    892913        elif index == 5: 
    893914            # Unselect All 2-D 
    894             for index in range(self.model.rowCount()): 
    895                 item = self.model.item(index) 
    896  
    897                 try: 
    898                     is2D = isinstance(GuiUtils.dataFromItem(item), Data2D) 
    899                 except AttributeError: 
    900                     msg = "Bad structure of the data model." 
    901                     raise RuntimeError(msg) 
    902  
    903                 if item.isCheckable() and item.checkState() == QtCore.Qt.Checked and is2D: 
    904                     item.setCheckState(QtCore.Qt.Unchecked) 
     915            self.setItemsCheckability(self.model, dimension=Data2D, checked=False) 
    905916 
    906917        else: 
     
    12701281        self.theory_model.appendRow(model_item) 
    12711282 
     1283    def deleteIntermediateTheoryPlotsByModelID(self, model_id): 
     1284        """Given a model's ID, deletes all items in the theory item model which reference the same ID. Useful in the 
     1285        case of intermediate results disappearing when changing calculations (in which case you don't want them to be 
     1286        retained in the list).""" 
     1287        items_to_delete = [] 
     1288        for r in range(self.theory_model.rowCount()): 
     1289            item = self.theory_model.item(r, 0) 
     1290            data = item.child(0).data() 
     1291            if not hasattr(data, "id"): 
     1292                return 
     1293            match = GuiUtils.theory_plot_ID_pattern.match(data.id) 
     1294            if match: 
     1295                item_model_id = match.groups()[-1] 
     1296                if item_model_id == model_id: 
     1297                    # Only delete those identified as an intermediate plot 
     1298                    if match.groups()[2] not in (None, ""): 
     1299                        items_to_delete.append(item) 
     1300 
     1301        for item in items_to_delete: 
     1302            self.theory_model.removeRow(item.row()) 
Note: See TracChangeset for help on using the changeset viewer.