source: sasview/src/sas/sasgui/guiframe/local_perspectives/data_loader/data_loader.py @ 74d9780

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 74d9780 was efe730d, checked in by Paul Kienzle <pkienzle@…>, 8 years ago

move sasview to src/sas/sasview and refactor bundled apps for easier debugging

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