source: sasview/src/sas/sasgui/guiframe/local_perspectives/data_loader/data_loader.py @ 5b2b04d

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 5b2b04d was c1d5aea, checked in by andyfaff, 8 years ago

MAINT: use 'x is not None', instead of 'not x is None'.

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