source: sasview/guiframe/local_perspectives/data_loader/data_loader.py @ 2399b2a

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 2399b2a was 52b8b74, checked in by Gervaise Alina <gervyh@…>, 14 years ago

working on guiframe

  • Property mode set to 100644
File size: 11.0 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_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       
43        hint_load_file = "Read state's files and load them into the application"
44        return [["Open State from File", hint_load_file, self.load_file]]
45 
46    def load_data(self, event):
47        """
48        Load data
49        """
50        flag = True
51        file_list = self.choose_data_file(flag)
52        if not file_list or file_list[0] is None:
53            return
54        self.get_data(file_list, flag=flag)
55       
56    def can_load_data(self):
57        """
58        if return True, then call handler to laod data
59        """
60        return True
61   
62    def load_file(self, event):
63        """
64        Load  sansview defined files
65        """
66        flag = False
67        file_list = self.choose_data_file(flag)
68        if not file_list or file_list[0] is None:
69            return
70        self.get_data(file_list, flag=flag)
71       
72    def load_folder(self, event):
73        """
74        Load entire folder
75        """
76        flag = True
77        path = self.choose_data_folder(flag)
78        if path is None:
79            return
80        file_list = self.get_file_path(path)
81        self.get_data(file_list, flag=flag)
82       
83    def get_wild_card(self, flag=True):
84        """
85        :param flag: is True load only data file, else load state file
86         return wild cards
87        """
88        if flag:
89            cards = self.loader.get_wildcards()
90            for item in STATE_FILE_EXT:
91                if item in cards:
92                    cards.remove(item)
93        else:
94            cards = STATE_FILE_EXT
95        return '|'.join(cards)
96       
97       
98    def choose_data_file(self, flag=True):
99        """
100        Open the file dialog to load file(s)
101        """
102        path = None
103        if self._default_save_location == None:
104            self._default_save_location = os.getcwd()
105       
106        cards = self.loader.get_wildcards()
107        wlist = self.get_wild_card(flag)
108        if flag:
109            style = wx.OPEN|wx.FD_MULTIPLE
110        else:
111            style = wx.OPEN|wx.FD_DEFAULT_STYLE
112           
113        dlg = wx.FileDialog(self.parent, 
114                            "Choose a file", 
115                            self._default_save_location, "",
116                             wlist,
117                             style=style)
118        if dlg.ShowModal() == wx.ID_OK:
119            path = dlg.GetPaths()
120            if len(path) >= 0 and not(path[0]is None):
121                self._default_save_location = os.path.dirname(path[0])
122        dlg.Destroy()
123        return path
124   
125    def choose_data_folder(self, flag=True):
126        """
127        :param flag: is True load only data file, else load state file
128        return a list of folder to read
129        """
130        path = None
131        if self._default_save_location == None:
132            self._default_save_location = os.getcwd()
133       
134        wlist = self.get_wild_card(flag)
135       
136        dlg = wx.DirDialog(self.parent, "Choose a directory", 
137                           self._default_save_location,
138                            style=wx.DD_DEFAULT_STYLE)
139        if dlg.ShowModal() == wx.ID_OK:
140            path = dlg.GetPath()
141            self._default_save_location = path
142        dlg.Destroy()
143        return path
144   
145    def load_error(self, error=None):
146        """
147        Pop up an error message.
148       
149        :param error: details error message to be displayed
150        """
151        message = "The data file you selected could not be loaded.\n"
152        message += "Make sure the content of your file"
153        message += " is properly formatted.\n\n"
154       
155        if error is not None:
156            message += "When contacting the DANSE team, mention the"
157            message += " following:\n%s" % str(error)
158        dial = wx.MessageDialog(self.parent, message, 'Error Loading File',
159                                wx.OK | wx.ICON_EXCLAMATION)
160        dial.ShowModal() 
161       
162    def get_file_path(self, path):
163        """
164        Receive a list containing folder then return a list of file
165        """
166        if os.path.isdir(path):
167            return [os.path.join(os.path.abspath(path),
168                                  file) for file in os.listdir(path)]
169   
170    def get_data(self, path, format=None, flag=True):
171        """
172        """
173        message = ""
174        log_msg = ''
175        output = []
176        error_message = ""
177        for p_file in path:
178            basename  = os.path.basename(p_file)
179            root, extension = os.path.splitext(basename)
180            if flag:
181                if extension.lower() in EXTENSIONS:
182                    log_msg = "Data Loader cannot "
183                    log_msg += "load: %s\n" % str(p_file)
184                    log_msg += "Try File -> open ...."
185                    logging.info(log_msg)
186                    continue
187            else:
188                if extension.lower() not in EXTENSIONS:
189                    log_msg = "File Loader cannot"
190                    log_msg += " load: %s\n" % str(p_file)
191                    log_msg += "Try Data -> Load ...."
192                    logging.info(log_msg)
193                    continue
194            try:
195                temp =  self.loader.load(p_file)
196                if temp.__class__.__name__ == "list":
197                    for item in temp:
198                        data = self.create_data(item, p_file)
199                        output.append(data)
200                else:
201                    data = self.create_data(temp, p_file)
202                    output.append(data)
203                message = "Loading ..." + str(p_file) + "\n"
204                self.load_update(output=output, message=message)
205            except:
206                error_message = "Error while loading: %s\n" % str(p_file)
207                error_message += str(sys.exc_value) + "\n"
208                self.load_update(output=output, message=error_message)
209               
210        message = "Loading Complete! "
211        message += log_msg
212        self.load_complete(output=output, error_message=error_message,
213                       message=message, path=path)
214           
215   
216    def old_get_data(self, path, format=None, flag=True):
217        """
218        :param flag: is True load only data file, else load state file
219        Receive a list of file paths and return a list of Data objects
220        """
221        from .load_thread import DataReader
222        message = "Start Loading \n"
223        wx.PostEvent(self.parent, StatusEvent(status=message,
224                                              info="info", type="progress"))
225        calc_load = DataReader(loader=self.loader,
226                               path=path,
227                               flag=flag,
228                               transform_data=self.create_data,
229                               updatefn=self.load_update,
230                               completefn=self.load_complete)
231        calc_load.queue()
232       
233    def load_update(self, output=None, message=""):
234        """
235        print update on the status bar
236        """
237        if message != "":
238            wx.PostEvent(self.parent, StatusEvent(status=message,
239                                                  type="progress",
240                                                   info="warning"))
241       
242    def load_complete(self, output, message="", error_message="", path=None):
243        """
244         post message to  status bar and return list of data
245        """
246        wx.PostEvent(self.parent, StatusEvent(status=message,
247                                              info="warning",
248                                              type="stop"))
249        if error_message != "":
250            self.load_error(error_message)
251        self.parent.add_data(output)
252       
253    def create_data(self, data, path):
254        """
255        Receive data from loader and create a data to use for guiframe
256        """
257       
258        if issubclass(DataInfo.Data2D, data.__class__):
259            new_plot = Data2D(image=None, err_image=None) 
260        else: 
261            new_plot = Data1D(x=[], y=[], dx=None, dy=None)
262           
263        new_plot.copy_from_datainfo(data) 
264        data.clone_without_data(clone=new_plot) 
265        #creating a name for data
266        name = ""
267        title = ""
268        file_name = ""
269        if path is not None:
270            file_name = os.path.basename(path)
271        if data.run:
272            name = data.run[0]
273        if name == "":
274            name = file_name
275        ## name of the data allow to differentiate data when plotted
276        name = parse_name(name=name, expression="_")
277       
278        max_char = name.find("[")
279        if max_char < 0:
280            max_char = len(name)
281        name = name[0:max_char]
282       
283        if name not in self.data_name_dict:
284            self.data_name_dict[name] = 0
285        else:
286            self.data_name_dict[name] += 1
287            name = name + " [" + str(self.data_name_dict[name]) + "]"
288        #find title
289        if data.title.strip():
290            title = data.title
291        if title.strip() == "":
292            title = file_name
293       
294        if new_plot.filename.strip() == "":
295            new_plot.filename = file_name
296       
297        new_plot.name = name
298        new_plot.title = title
299        ## allow to highlight data when plotted
300        new_plot.interactive = True
301        ## when 2 data have the same id override the 1 st plotted
302        new_plot.id = name
303        ##group_id specify on which panel to plot this data
304        new_plot.group_id = name
305        new_plot.is_data = True
306        new_plot.path = path
307        ##post data to plot
308        # plot data
309        return new_plot
310       
311       
Note: See TracBrowser for help on using the repository browser.