source: sasview/invariantview/perspectives/invariant/invariant.py @ b24cfd9

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

check is the data is not none before trying to remove it

  • Property mode set to 100644
File size: 12.5 KB
Line 
1
2
3
4################################################################################
5#This software was developed by the University of Tennessee as part of the
6#Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
7#project funded by the US National Science Foundation.
8#
9#See the license text in license.txt
10#
11#copyright 2009, University of Tennessee
12################################################################################
13
14
15import sys
16import wx
17import copy
18import logging
19
20
21from sans.guiframe.dataFitting import Data1D
22from sans.guiframe.events import NewPlotEvent
23from sans.guiframe.gui_style import GUIFRAME_ID
24from .invariant_state import Reader as reader
25from DataLoader.loader import Loader
26from .invariant_panel import InvariantPanel
27from sans.guiframe.plugin_base import PluginBase
28
29class Plugin(PluginBase):
30    """
31    This class defines the interface for invariant Plugin class
32    that can be used by the gui_manager.       
33    """
34   
35    def __init__(self, standalone=False):
36        PluginBase.__init__(self, name="Invariant", standalone=standalone)
37       
38        #dictionary containing data name and error on dy of that data
39        self.err_dy = {}
40       
41        #default state objects
42        self.state_reader = None 
43        self._extensions = '.inv'
44        self.temp_state = None 
45        self.__data = None 
46       
47        # Log startup
48        logging.info("Invariant plug-in started")
49       
50    def help(self, evt):
51        """
52        Show a general help dialog.
53        """
54        from .help_panel import  HelpWindow
55        frame = HelpWindow(None, -1)   
56        frame.Show(True)
57       
58    def get_data(self):
59        """
60        """
61        return self.__data
62   
63    def get_panels(self, parent):
64        """
65        Create and return the list of wx.Panels for your plug-in.
66        Define the plug-in perspective.
67       
68        Panels should inherit from DefaultPanel defined below,
69        or should present the same interface. They must define
70        "window_caption" and "window_name".
71       
72        :param parent: parent window
73       
74        :return: list of panels
75        """
76        ## Save a reference to the parent
77        self.parent = parent
78        self.invariant_panel = InvariantPanel(parent=self.parent)
79        self.invariant_panel.set_manager(manager=self)
80        self.perspective.append(self.invariant_panel.window_name) 
81        #Create reader when fitting panel are created
82        self.state_reader = reader(self.set_state)   
83        #append that reader to list of available reader
84        loader = Loader()
85        loader.associate_file_reader(".inv", self.state_reader)
86        loader.associate_file_reader(".svs", self.state_reader)
87        # Return the list of panels
88        return [self.invariant_panel]
89 
90    def get_context_menu(self, plotpanel=None):
91        """
92        This method is optional.
93   
94        When the context menu of a plot is rendered, the
95        get_context_menu method will be called to give you a
96        chance to add a menu item to the context menu.
97       
98        A ref to a Graph object is passed so that you can
99        investigate the plot content and decide whether you
100        need to add items to the context menu. 
101       
102        This method returns a list of menu items.
103        Each item is itself a list defining the text to
104        appear in the menu, a tool-tip help text, and a
105        call-back method.
106       
107        :param graph: the Graph object to which we attach the context menu
108       
109        :return: a list of menu items with call-back function
110        """
111        graph = plotpanel.graph
112        invariant_option = "Compute invariant"
113        invariant_hint = "Will displays the invariant panel for"
114        invariant_hint += " further computation"
115       
116        if graph.selected_plottable not in plotpanel.plots:
117            return []
118        data = plotpanel.plots[graph.selected_plottable]
119       
120        if issubclass(data.__class__, Data1D):
121           if data.name != "$I_{obs}(q)$" and  data.name != " $P_{fit}(r)$":
122               return [[invariant_option, invariant_hint, 
123                                        self._compute_invariant]]
124        return []
125
126    def _compute_invariant(self, event):   
127        """
128        Open the invariant panel to invariant computation
129        """
130        self.panel = event.GetEventObject()
131        Plugin.on_perspective(self, event=event)
132        id = self.panel.graph.selected_plottable
133        data = self.panel.plots[self.panel.graph.selected_plottable]
134        if data is None:
135            return
136        if not issubclass(data.__class__, Data1D):
137            name = data.__class__.__name__
138            msg = "Invariant use only Data1D got: [%s] " % str(name)
139            raise ValueError, msg
140        self.compute_helper(data=data)
141               
142    def set_data(self, data_list=None):
143        """
144        receive a list of data and compute invariant
145        """
146        data = None
147        if data_list is None:
148            data_list = []
149        if len(data_list) >= 1:
150            if len(data_list) == 1:
151                data = data_list[0]
152            else:
153                msg = "invariant panel does not allow multiple data!\n"
154                msg += "Please select one.\n"
155                from invariant_widgets import DataDialog
156                dlg = DataDialog(data_list=data_list, text=msg)
157                if dlg.ShowModal() == wx.ID_OK:
158                    data = dlg.get_data()
159            if data is None:
160                return
161            if issubclass(data.__class__, Data1D):
162                wx.PostEvent(self.parent, NewPlotEvent(plot=data,
163                                           title=data.title))
164                try:
165                    self.compute_helper(data)
166                except:
167                    msg = "Prview Set_data: " + str(sys.exc_value)
168                    wx.PostEvent(self.parent, StatusEvent(status=msg,
169                                                                info="error"))
170        else:   
171            msg = "invariant cannot be computed for data of "
172            msg += "type %s" % (data.__class__.__name__)
173            wx.PostEvent(self.parent, 
174                     StatusEvent(status=msg, info='error'))
175    def delete_data(self, data_id):
176        """
177        """
178        if self.__data is None:
179            return
180        for id in data_id:
181            if id == self.__data.id:
182                self.clear_panel()
183               
184    def clear_panel(self):
185        """
186        """
187        self.invariant_panel.clear_panel()
188       
189    def compute_helper(self, data):
190        """
191        """
192        if data is None:
193            return 
194        # set current data if not it's a state data
195        if not self.invariant_panel.is_state_data:
196            # Store reference to data
197            self.__data = data
198            # Set the data set to be user for invariant calculation
199            self.invariant_panel.set_data(data=data)
200           
201    def save_file(self, filepath, state=None):
202        """
203        Save data in provided state object.
204               
205        :param filepath: path of file to write to
206        :param state: invariant state
207        """     
208        # Write the state to file
209        # First, check that the data is of the right type
210        current_plottable = self.__data
211
212        if issubclass(current_plottable.__class__, LoaderData1D):
213            self.state_reader.write(filepath, current_plottable, state)
214        else:
215            msg = "invariant.save_file: the data being saved is"
216            msg += " not a DataLoader.data_info.Data1D object" 
217            raise RuntimeError, msg
218
219    def set_state(self, state=None, datainfo=None):   
220        """
221        Call-back method for the state reader.
222        This method is called when a .inv/.svs file is loaded.
223       
224        :param state: State object
225        """
226        self.temp_state = None
227        try:
228            if datainfo.__class__.__name__ == 'list':
229                data = datainfo[0]
230            else:
231                data = datainfo
232            if data is None:
233                msg = "invariant.set_state: datainfo parameter cannot"
234                msg += " be None in standalone mode"
235                raise RuntimeError, msg
236           
237            name = data.meta_data['invstate'].file
238            data.meta_data['invstate'].file = name
239            data.name = name
240            data.filename = name
241            data = self.parent.create_gui_data(data,None)
242            self.__data = data
243            wx.PostEvent(self.parent, NewPlotEvent(plot=self.__data,
244                                        reset=True, title=self.__data.title))
245            data_dict = {self.__data.id:self.__data}
246            self.parent.add_data(data_list=data_dict)
247            # set state
248            self.invariant_panel.is_state_data = True
249           
250            # Make sure the user sees the invariant panel after loading
251            #self.parent.set_perspective(self.perspective)
252            self.on_perspective(event=None)
253            # Load the invariant states
254            self.temp_state = state
255            self.invariant_panel.set_state(state=state,data=self.__data)         
256           
257        except: 
258            logging.error("invariant.set_state: %s" % sys.exc_value)
259           
260    def on_set_state_helper(self, event=None):
261        """
262        Set the state when called by EVT_STATE_UPDATE event from guiframe
263        after a .inv/.svs file is loaded
264        """
265        self.invariant_panel.set_state(state=self.temp_state,
266                                       data=self.__data)
267        self.temp_state = None
268       
269       
270    def plot_theory(self, data=None, name=None):
271        """
272        Receive a data set and post a NewPlotEvent to parent.
273       
274        :param data: extrapolated data to be plotted
275        :param name: Data's name to use for the legend
276        """
277        #import copy
278        if data is None:
279            id = str(self.__data.id) + name
280            group_id = self.__data.group_id
281            wx.PostEvent(self.parent, NewPlotEvent(id=id,
282                                               group_id=group_id,
283                                               action='Remove'))
284            return
285   
286        new_plot = Data1D(x=[], y=[], dy=None)
287        new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
288        scale = self.invariant_panel.get_scale()
289        background = self.invariant_panel.get_background()
290       
291        if scale != 0:
292            # Put back the sacle and bkg for plotting
293            data.y = (data.y + background)/scale
294            new_plot = Data1D(x=data.x, y=data.y, dy=None)
295            new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
296        else:
297            msg = "Scale can not be zero."
298            raise ValueError, msg
299        if len(new_plot.x)== 0 :
300            return
301       
302        new_plot.name = name
303        new_plot.xaxis(self.__data._xaxis, self.__data._xunit)
304        new_plot.yaxis(self.__data._yaxis, self.__data._yunit)
305        new_plot.group_id = self.__data.group_id
306        new_plot.id = str(self.__data.id) + name
307        new_plot.title = self.__data.title
308        # Save theory_data in a state
309        if data != None:
310            name_head = name.split('-')
311            if name_head[0] == 'Low':
312                self.invariant_panel.state.theory_lowQ = copy.deepcopy(new_plot)
313            elif name_head[0] == 'High':
314                self.invariant_panel.state.theory_highQ =copy.deepcopy(new_plot)
315           
316        self.parent.update_theory(data_id=self.__data.id, theory=new_plot)
317        wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot,
318                                               title=self.__data.title))
319       
320    def plot_data(self, scale, background):
321        """
322        replot the current data if the user enters a new scale or background
323        """
324        new_plot = scale * self.__data - background
325        new_plot.name = self.__data.name
326        new_plot.group_id = self.__data.group_id
327        new_plot.id = self.__data.id
328        new_plot.title = self.__data.title
329       
330        # Save data in a state: but seems to never happen
331        if new_plot != None:
332            self.invariant_panel.state.data = copy.deepcopy(new_plot)
333        wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot,
334                                               title=new_plot.title))
335       
Note: See TracBrowser for help on using the repository browser.