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

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

working on guiframe loading

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