source: sasview/src/sas/sasgui/guiframe/local_perspectives/data_loader/data_loader.py @ 914ba0a

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalcmagnetic_scattrelease-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 914ba0a was 914ba0a, checked in by Paul Kienzle <pkienzle@…>, 7 years ago

merge with master

  • Property mode set to 100644
File size: 9.1 KB
Line 
1
2"""
3plugin DataLoader responsible of loading data
4"""
5import os
6import sys
7import wx
8import logging
9
10logger = logging.getLogger(__name__)
11
12from sas.sascalc.dataloader.loader import Loader
13
14from sas.sasgui import get_local_config
15from sas.sasgui.guiframe.plugin_base import PluginBase
16from sas.sasgui.guiframe.events import StatusEvent
17from sas.sasgui.guiframe.gui_style import GUIFRAME
18from sas.sasgui.guiframe.gui_manager import DEFAULT_OPEN_FOLDER
19
20config = get_local_config()
21extension_list = []
22if config.APPLICATION_STATE_EXTENSION is not None:
23    extension_list.append(config.APPLICATION_STATE_EXTENSION)
24EXTENSIONS = config.PLUGIN_STATE_EXTENSIONS + extension_list
25PLUGINS_WLIST = config.PLUGINS_WLIST
26APPLICATION_WLIST = config.APPLICATION_WLIST
27
28class Plugin(PluginBase):
29
30    def __init__(self):
31        PluginBase.__init__(self, name="DataLoader")
32        # Default location
33        self._default_save_location = DEFAULT_OPEN_FOLDER
34        self.loader = Loader()
35        self._data_menu = None
36
37    def populate_file_menu(self):
38        """
39        get a menu item and append it under file menu of the application
40        add load file menu item and load folder item
41        """
42        # menu for data files
43        menu_list = []
44        data_file_hint = "load one or more data in the application"
45        menu_list = [('&Load Data File(s)', data_file_hint, self.load_data)]
46        gui_style = self.parent.get_style()
47        style = gui_style & GUIFRAME.MULTIPLE_APPLICATIONS
48        style1 = gui_style & GUIFRAME.DATALOADER_ON
49        if style == GUIFRAME.MULTIPLE_APPLICATIONS:
50            # menu for data from folder
51            data_folder_hint = "load multiple data in the application"
52            menu_list.append(('&Load Data Folder', data_folder_hint,
53                              self._load_folder))
54        return menu_list
55
56    def load_data(self, event):
57        """
58        Load data
59        """
60        path = None
61        self._default_save_location = self.parent._default_save_location
62        if self._default_save_location is None:
63            self._default_save_location = os.getcwd()
64
65        cards = self.loader.get_wildcards()
66        temp = [APPLICATION_WLIST] + PLUGINS_WLIST
67        for item in temp:
68            if item in cards:
69                cards.remove(item)
70        wlist = '|'.join(cards)
71        style = wx.OPEN | wx.FD_MULTIPLE
72        dlg = wx.FileDialog(self.parent,
73                            "Choose a file",
74                            self._default_save_location, "",
75                            wlist,
76                            style=style)
77        if dlg.ShowModal() == wx.ID_OK:
78            file_list = dlg.GetPaths()
79            if len(file_list) >= 0 and file_list[0] is not None:
80                self._default_save_location = os.path.dirname(file_list[0])
81                path = self._default_save_location
82        dlg.Destroy()
83
84        if path is None or not file_list or file_list[0] is None:
85            return
86        self.parent._default_save_location = self._default_save_location
87        self.get_data(file_list)
88
89
90    def can_load_data(self):
91        """
92        if return True, then call handler to laod data
93        """
94        return True
95
96
97    def _load_folder(self, event):
98        """
99        Load entire folder
100        """
101        path = None
102        self._default_save_location = self.parent._default_save_location
103        if self._default_save_location is None:
104            self._default_save_location = os.getcwd()
105        dlg = wx.DirDialog(self.parent, "Choose a directory",
106                           self._default_save_location,
107                           style=wx.DD_DEFAULT_STYLE)
108        if dlg.ShowModal() == wx.ID_OK:
109            path = dlg.GetPath()
110            self._default_save_location = path
111        dlg.Destroy()
112        if path is not None:
113            self._default_save_location = os.path.dirname(path)
114        else:
115            return
116        file_list = self.get_file_path(path)
117        self.get_data(file_list)
118        self.parent._default_save_location = self._default_save_location
119
120    def load_error(self, error=None):
121        """
122        Pop up an error message.
123
124        :param error: details error message to be displayed
125        """
126        if error is not None or str(error).strip() != "":
127            dial = wx.MessageDialog(self.parent, str(error), 'Error Loading File',
128                                    wx.OK | wx.ICON_EXCLAMATION)
129            dial.ShowModal()
130
131    def get_file_path(self, path):
132        """
133        Receive a list containing folder then return a list of file
134        """
135        if os.path.isdir(path):
136            return [os.path.join(os.path.abspath(path), filename) for filename in os.listdir(path)]
137
138    def _process_data_and_errors(self, item, p_file, output, message):
139        """
140        Check to see if data set loaded with any errors. If so, append to
141            error message to be sure user knows the issue.
142        """
143        data_error = False
144        if hasattr(item, 'errors'):
145            for error_data in item.errors:
146                data_error = True
147                message += "\tError: {0}\n".format(error_data)
148        else:
149            logger.error("Loader returned an invalid object:\n %s" % str(item))
150            data_error = True
151
152        data = self.parent.create_gui_data(item, p_file)
153        output[data.id] = data
154        return output, message, data_error
155
156    def get_data(self, path, format=None):
157        """
158        """
159        file_errors = {}
160        output = {}
161        exception_occurred = False
162
163        for p_file in path:
164            basename = os.path.basename(p_file)
165            _, extension = os.path.splitext(basename)
166            if extension.lower() in EXTENSIONS:
167                log_msg = "Data Loader cannot "
168                log_msg += "load: {}\n".format(str(p_file))
169                log_msg += "Please try to open that file from \"open project\""
170                log_msg += "or \"open analysis\" menu."
171                logger.info(log_msg)
172                file_errors[basename] = [log_msg]
173                continue
174
175            try:
176                message = "Loading {}...\n".format(p_file)
177                self.load_update(output=output, message=message, info="info")
178                temp = self.loader.load(p_file, format)
179                if not isinstance(temp, list):
180                    temp = [temp]
181                for item in temp:
182                    error_message = ""
183                    output, error_message, data_error = \
184                        self._process_data_and_errors(item,
185                                                      p_file,
186                                                      output,
187                                                      error_message)
188                    if data_error:
189                        if basename in file_errors.keys():
190                            file_errors[basename] += [error_message]
191                        else:
192                            file_errors[basename] = [error_message]
193                        self.load_update(output=output,
194                            message=error_message, info="warning")
195
196                self.load_update(output=output,
197                message="Loaded {}\n".format(p_file),
198                info="info")
199
200            except:
201                logger.error(sys.exc_value)
202
203                error_message = "The Data file you selected could not be loaded.\n"
204                error_message += "Make sure the content of your file"
205                error_message += " is properly formatted.\n"
206                error_message += "When contacting the SasView team, mention the"
207                error_message += " following:\n"
208                error_message += "Error: " + str(sys.exc_info()[1])
209                file_errors[basename] = [error_message]
210                self.load_update(output=output, message=error_message, info="warning")
211
212        if len(file_errors) > 0:
213            error_message = ""
214            for filename, error_array in file_errors.iteritems():
215                error_message += "The following errors occured whilst "
216                error_message += "loading {}:\n".format(filename)
217                for message in error_array:
218                    error_message += message + "\n"
219                error_message += "\n"
220            self.load_update(output=output, message=error_message, info="error")
221
222        self.load_complete(output=output, message="Loading data complete!",
223            info="info")
224
225    def load_update(self, output=None, message="", info="warning"):
226        """
227        print update on the status bar
228        """
229        if message != "":
230            wx.PostEvent(self.parent, StatusEvent(status=message, info=info,
231                                                  type="progress"))
232    def load_complete(self, output, message="", error_message="", path=None,
233                      info="warning"):
234        """
235         post message to  status bar and return list of data
236        """
237        wx.PostEvent(self.parent, StatusEvent(status=message,
238                                              info=info,
239                                              type="stop"))
240        # if error_message != "":
241        #    self.load_error(error_message)
242        self.parent.add_data(data_list=output)
Note: See TracBrowser for help on using the repository browser.