source: sasview/src/sas/qtgui/Perspectives/Fitting/FittingPerspective.py @ 125c4be

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since 125c4be was 125c4be, checked in by Piotr Rozyczko <rozyczko@…>, 7 years ago

Allow rebuilding of the categories file and plugin_models dir

  • Property mode set to 100644
File size: 4.1 KB
Line 
1import numpy
2
3from PyQt4 import QtCore
4from PyQt4 import QtGui
5
6import sas.qtgui.Utilities.ObjectLibrary as ObjectLibrary
7
8from sas.qtgui.Perspectives.Fitting.FittingWidget import FittingWidget
9from sas.qtgui.Perspectives.Fitting import ModelUtilities
10
11class FittingWindow(QtGui.QTabWidget):
12    """
13    """
14    name = "Fitting" # For displaying in the combo box in DataExplorer
15    def __init__(self, parent=None, data=None):
16        super(FittingWindow, self).__init__()
17
18        self.parent = parent
19        self._data = data
20
21        # List of active fits
22        self.tabs = []
23
24        # Max index for adding new, non-clashing tab names
25        self.maxIndex = 0
26
27        # Index of the current tab
28        self.currentTab = 0
29
30        # The current optimizer
31        self.optimizer = 'Levenberg-Marquardt'
32
33        # The tabs need to be closeable
34        self.setTabsClosable(True)
35
36        self.communicate = self.parent.communicator()
37
38        # Initialize the first tab
39        self.addFit(None)
40
41        # Deal with signals
42        self.tabCloseRequested.connect(self.tabCloses)
43
44        # Perspective window not allowed to close by default
45        self._allow_close = False
46
47        self.menu_manager = ModelUtilities.ModelManager()
48        # TODO: reuse these in FittingWidget properly
49        self.model_list_box = self.menu_manager.get_model_list()
50        self.model_dictionary = self.menu_manager.get_model_dictionary()
51
52        self.setWindowTitle('Fit panel - Active Fitting Optimizer: %s' % self.optimizer)
53
54    def setClosable(self, value=True):
55        """
56        Allow outsiders close this widget
57        """
58        assert isinstance(value, bool)
59
60        self._allow_close = value
61
62    def closeEvent(self, event):
63        """
64        Overwrite QDialog close method to allow for custom widget close
65        """
66        # Invoke fit page events
67        for tab in self.tabs:
68            tab.close()
69        if self._allow_close:
70            # reset the closability flag
71            self.setClosable(value=False)
72            event.accept()
73        else:
74            # Maybe we should just minimize
75            self.setWindowState(QtCore.Qt.WindowMinimized)
76            event.ignore()
77
78    def addFit(self, data):
79        """
80        Add a new tab for passed data
81        """
82        tab     = FittingWidget(parent=self.parent, data=data, tab_id=self.maxIndex+1)
83        # Add this tab to the object library so it can be retrieved by scripting/jupyter
84        ObjectLibrary.addObject(self.tabName(), tab)
85        self.tabs.append(tab)
86        self.maxIndex += 1
87        self.addTab(tab, self.tabName())
88
89    def tabName(self):
90        """
91        Get the new tab name, based on the number of fitting tabs so far
92        """
93        page_name = "FitPage" + str(self.maxIndex)
94        return page_name
95
96    def tabCloses(self, index):
97        """
98        Update local bookkeeping on tab close
99        """
100        assert len(self.tabs) >= index
101        # don't remove the last tab
102        if len(self.tabs) <= 1:
103            return
104        ObjectLibrary.deleteObjectByRef(self.tabs[index])
105        del self.tabs[index]
106        self.removeTab(index)
107
108    def allowBatch(self):
109        """
110        Tell the caller that we accept multiple data instances
111        """
112        return True
113
114    def setData(self, data_item=None):
115        """
116        Assign new dataset to the fitting instance
117        Obtain a QStandardItem object and dissect it to get Data1D/2D
118        Pass it over to the calculator
119        """
120        assert data_item is not None
121
122        if not isinstance(data_item, list):
123            msg = "Incorrect type passed to the Fitting Perspective"
124            raise AttributeError, msg
125
126        if not isinstance(data_item[0], QtGui.QStandardItem):
127            msg = "Incorrect type passed to the Fitting Perspective"
128            raise AttributeError, msg
129
130        for data in data_item:
131            # Find the first unassigned tab.
132            # If none, open a new tab.
133            available_tabs = list(map(lambda tab: tab.acceptsData(), self.tabs))
134
135            if numpy.any(available_tabs):
136                self.tabs[available_tabs.index(True)].data = data
137            else:
138                self.addFit(data)
Note: See TracBrowser for help on using the repository browser.