source: sasview/guiframe/local_perspectives/data_loader/data_loader.py @ 88989768

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.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 88989768 was de48a1a, checked in by Gervaise Alina <gervyh@…>, 14 years ago

change order of popo up window

  • Property mode set to 100644
File size: 11.8 KB
Line 
1
2"""
3plugin DataLoader responsible of loading data
4"""
5import os
6import sys
7import wx
8import logging
9
10from DataLoader.loader import Loader
11import DataLoader.data_info as DataInfo
12from sans.guiframe.plugin_base import PluginBase
13from sans.guiframe.events import StatusEvent
14from sans.guiframe.events import NewPlotEvent
15from sans.guiframe.dataFitting import Data1D
16from sans.guiframe.dataFitting import Data2D
17from sans.guiframe.utils import parse_name
18
19STATE_FILE_EXT = ['P(r) files (*.prv)|*.prv',
20                  'P(r) files (*.sav)|*.sav',
21                  'P(r) files (*.svs)|*.svs',
22                  'Fitting files (*.fitv)|*.fitv',
23                  'Fitting files (*.svs)|*.svs',
24                  'Invariant files (*.inv)|*.inv',
25                  'Invariant files (*.svs)|*.svs']
26EXTENSIONS = ['.svs', '.prv', '.inv', '.fitv']
27
28class Plugin(PluginBase):
29   
30    def __init__(self, standalone=False):
31        PluginBase.__init__(self, name="DataLoader", standalone=standalone)
32        #Default location
33        self._default_save_location = None 
34        self.data_name_dict = {}
35        self.loader = Loader()   
36       
37    def populate_menu(self, id, owner):
38        """
39        Create a menu for the Data plug-in
40       
41        :param id: id to create a menu
42        :param owner: owner of menu
43       
44        :return: list of information to populate the main menu
45       
46        """
47        #Menu for data loader
48        self.menu = wx.Menu()
49        #menu for data files
50        data_file_id = wx.NewId()
51        data_file_hint = "load one or more data in the application"
52        self.menu.Append(data_file_id, 
53                         '&Load Data File(s)', data_file_hint)
54        wx.EVT_MENU(owner, data_file_id, self._load_data)
55        #menu for data from folder
56        data_folder_id = wx.NewId()
57        data_folder_hint = "load multiple data in the application"
58        self.menu.Append(data_folder_id, 
59                         '&Load Data Folder', data_folder_hint)
60        wx.EVT_MENU(owner, data_folder_id, self._load_folder)
61        #create  menubar items
62        return [(id, self.menu, "Data")]
63   
64    def populate_file_menu(self):
65        """
66        get a menu item and append it under file menu of the application
67        add load file menu item and load folder item
68        """
69       
70        hint_load_file = "Read state's files and load them into the application"
71        return [["Open State from File", hint_load_file, self._load_file]]
72 
73    def _load_data(self, event):
74        """
75        Load data
76        """
77        flag = True
78        file_list = self.choose_data_file(flag)
79        if not file_list or file_list[0] is None:
80            return
81        self.get_data(file_list, flag=flag)
82       
83    def _load_file(self, event):
84        """
85        Load  sansview defined files
86        """
87        flag = False
88        file_list = self.choose_data_file(flag)
89        if not file_list or file_list[0] is None:
90            return
91        self.get_data(file_list, flag=flag)
92       
93    def _load_folder(self, event):
94        """
95        Load entire folder
96        """
97        flag = True
98        path = self.choose_data_folder(flag)
99        if path is None:
100            return
101        file_list = self.get_file_path(path)
102        self.get_data(file_list, flag=flag)
103   
104    def get_wild_card(self, flag=True):
105        """
106        :param flag: is True load only data file, else load state file
107         return wild cards
108        """
109        if flag:
110            cards = self.loader.get_wildcards()
111            for item in STATE_FILE_EXT:
112                if item in cards:
113                    cards.remove(item)
114        else:
115            cards = STATE_FILE_EXT
116        return '|'.join(cards)
117       
118       
119    def choose_data_file(self, flag=True):
120        """
121        Open the file dialog to load file(s)
122        """
123        path = None
124        if self._default_save_location == None:
125            self._default_save_location = os.getcwd()
126       
127        cards = self.loader.get_wildcards()
128        wlist = self.get_wild_card(flag)
129        if flag:
130            style = wx.OPEN|wx.FD_MULTIPLE
131        else:
132            style = wx.OPEN|wx.FD_DEFAULT_STYLE
133           
134        dlg = wx.FileDialog(self.parent, 
135                            "Choose a file", 
136                            self._default_save_location, "",
137                             wlist,
138                             style=style)
139        if dlg.ShowModal() == wx.ID_OK:
140            path = dlg.GetPaths()
141            if len(path) >= 0 and not(path[0]is None):
142                self._default_save_location = os.path.dirname(path[0])
143        dlg.Destroy()
144        return path
145   
146    def choose_data_folder(self, flag=True):
147        """
148        :param flag: is True load only data file, else load state file
149        return a list of folder to read
150        """
151        path = None
152        if self._default_save_location == None:
153            self._default_save_location = os.getcwd()
154       
155        wlist = self.get_wild_card(flag)
156       
157        dlg = wx.DirDialog(self.parent, "Choose a directory", 
158                           self._default_save_location,
159                            style=wx.DD_DEFAULT_STYLE)
160        if dlg.ShowModal() == wx.ID_OK:
161            path = dlg.GetPath()
162            self._default_save_location = path
163        dlg.Destroy()
164        return path
165   
166    def load_error(self, error=None):
167        """
168        Pop up an error message.
169       
170        :param error: details error message to be displayed
171        """
172        message = "The data file you selected could not be loaded.\n"
173        message += "Make sure the content of your file"
174        message += " is properly formatted.\n\n"
175       
176        if error is not None:
177            message += "When contacting the DANSE team, mention the"
178            message += " following:\n%s" % str(error)
179        dial = wx.MessageDialog(self.parent, message, 'Error Loading File',
180                                wx.OK | wx.ICON_EXCLAMATION)
181        dial.ShowModal() 
182       
183    def get_file_path(self, path):
184        """
185        Receive a list containing folder then return a list of file
186        """
187        if os.path.isdir(path):
188            return [os.path.join(os.path.abspath(path),
189                                  file) for file in os.listdir(path)]
190   
191    def get_data(self, path, format=None, flag=True):
192        """
193        """
194        message = ""
195        log_msg = ''
196        output = []
197        error_message = ""
198        for p_file in path:
199            basename  = os.path.basename(p_file)
200            root, extension = os.path.splitext(basename)
201            if flag:
202                if extension.lower() in EXTENSIONS:
203                    log_msg = "Data Loader cannot "
204                    log_msg += "load: %s\n" % str(p_file)
205                    log_msg += "Try File -> open ...."
206                    logging.info(log_msg)
207                    continue
208            else:
209                if extension.lower() not in EXTENSIONS:
210                    log_msg = "File Loader cannot"
211                    log_msg += " load: %s\n" % str(p_file)
212                    log_msg += "Try Data -> Load ...."
213                    logging.info(log_msg)
214                    continue
215            try:
216                temp =  self.loader.load(p_file)
217                if temp.__class__.__name__ == "list":
218                    for item in temp:
219                        data = self.create_data(item, p_file)
220                        output.append(data)
221                else:
222                    data = self.create_data(temp, p_file)
223                    output.append(data)
224                message = "Loading ..." + str(p_file) + "\n"
225                self.load_update(output=output, message=message)
226            except:
227                error_message = "Error while loading: %s\n" % str(p_file)
228                error_message += str(sys.exc_value) + "\n"
229                self.load_update(output=output, message=error_message)
230               
231        message = "Loading Complete! "
232        message += log_msg
233        self.load_complete(output=output, error_message=error_message,
234                       message=message, path=path)
235           
236   
237    def old_get_data(self, path, format=None, flag=True):
238        """
239        :param flag: is True load only data file, else load state file
240        Receive a list of file paths and return a list of Data objects
241        """
242        from .load_thread import DataReader
243        message = "Start Loading \n"
244        wx.PostEvent(self.parent, StatusEvent(status=message,
245                                              info="info", type="progress"))
246        calc_load = DataReader(loader=self.loader,
247                               path=path,
248                               flag=flag,
249                               transform_data=self.create_data,
250                               updatefn=self.load_update,
251                               completefn=self.load_complete)
252        calc_load.queue()
253       
254    def load_update(self, output=None, message=""):
255        """
256        print update on the status bar
257        """
258        if message != "":
259            wx.PostEvent(self.parent, StatusEvent(status=message,
260                                                  type="progress",
261                                                   info="warning"))
262       
263    def load_complete(self, output, message="", error_message="", path=None):
264        """
265         post message to  status bar and return list of data
266        """
267        wx.PostEvent(self.parent, StatusEvent(status=message,
268                                              info="warning",
269                                              type="stop"))
270        if error_message != "":
271            self.load_error(error_message)
272        self.parent.add_data(output)
273       
274    def create_data(self, data, path):
275        """
276        Receive data from loader and create a data to use for guiframe
277        """
278       
279        if issubclass(DataInfo.Data2D, data.__class__):
280            new_plot = Data2D(image=None, err_image=None) 
281        else: 
282            new_plot = Data1D(x=[], y=[], dx=None, dy=None)
283           
284        new_plot.copy_from_datainfo(data) 
285        data.clone_without_data(clone=new_plot) 
286        #creating a name for data
287        name = ""
288        title = ""
289        file_name = ""
290        if path is not None:
291            file_name = os.path.basename(path)
292        if data.run:
293            name = data.run[0]
294        if name == "":
295            name = file_name
296        ## name of the data allow to differentiate data when plotted
297        name = parse_name(name=name, expression="_")
298       
299        max_char = name.find("[")
300        if max_char < 0:
301            max_char = len(name)
302        name = name[0:max_char]
303       
304        if name not in self.data_name_dict:
305            self.data_name_dict[name] = 0
306        else:
307            self.data_name_dict[name] += 1
308            name = name + " [" + str(self.data_name_dict[name]) + "]"
309        #find title
310        if data.title.strip():
311            title = data.title
312        if title.strip() == "":
313            title = file_name
314       
315        if new_plot.filename.strip() == "":
316            new_plot.filename = file_name
317       
318        new_plot.name = name
319        new_plot.title = title
320        ## allow to highlight data when plotted
321        new_plot.interactive = True
322        ## when 2 data have the same id override the 1 st plotted
323        new_plot.id = name
324        ##group_id specify on which panel to plot this data
325        new_plot.group_id = name
326        new_plot.is_data = True
327        new_plot.path = path
328        ##post data to plot
329        # plot data
330        return new_plot
331       
332       
Note: See TracBrowser for help on using the repository browser.