source: sasview/guiframe/stateManager.py @ 2bd9927

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 2bd9927 was ca88b2e, checked in by Gervaise Alina <gervyh@…>, 15 years ago

working on history panel

  • Property mode set to 100644
File size: 12.8 KB
Line 
1"""
2    Object to manage the state of the application
3"""
4
5import wx
6import wx.lib.newevent
7
8import ModelParameters
9import AveragerParameters
10import Averager2D
11import history
12import modelData
13from model_thread import Calc2D
14from copy import deepcopy
15from fitting import ChiUpdateEvent
16
17(Refresh2DEvent, EVT_2DREFRESH) = wx.lib.newevent.NewEvent()
18
19# Debug printout
20from config import printEVT
21import config
22from state import State
23import Plotter1D
24import Plotter2D
25
26(StateEvent, EVT_STATE)   = wx.lib.newevent.NewEvent()
27
28class DetectorMemento:
29    def __init__(self, qmax=0.1, npts=10, beam=None, zmin=None, zmax=None, sym4=False):
30        self.qmax = qmax
31        self.npts = npts
32        self.zmin = zmin
33        self.zmax = zmax
34        self.beam = beam
35        self.sym4 = sym4
36       
37    def toString(self, memento):
38        """
39            Return a string that describes the difference
40            between the given memento and the current one
41            @param memento: memento to compare to
42            @return: string
43        """
44        if memento == None:
45            return "/Qmax = %g/Det npts = %g" % (self.qmax, self.npts)
46        else:
47            descr = ''
48            if not memento.qmax == self.qmax:
49                descr += "/Qmax = %g" % self.qmax
50            if not memento.npts == self.npts:
51                descr += "/Det npts = %g" % self.npts
52            if not self.zmin==None and not memento.zmin == self.zmin:
53                descr += "/Zmin = %g" % self.zmin
54            if self.zmax and not memento.zmax == self.zmax:
55                descr += "/Zmax = %g" % self.zmax
56            if not memento.beam == self.beam:
57                descr += "/beamstop = %g" % self.beam
58            return descr
59
60class StateManager:
61   
62    def __init__(self, target=None, model=None, slicer=None):
63        self.target = target
64        self.state  = State(target, model, slicer)
65       
66        # Listen to parameter changes to fire history events
67
68        self.target.Bind(ModelParameters.EVT_MODEL_PARS, self._onEVT_MODEL_PARS)
69        self.target.Bind(AveragerParameters.EVT_AVG_PARS, self._onEVT_AVG_PARS)
70        self.target.Bind(EVT_STATE, self._onEVT_STATE)
71        self.target.Bind(Plotter2D.EVT_DETECTOR, self._onEVT_DETECTOR)
72        self.target.Bind(Plotter1D.EVT_PLOT1D_PARS, self._onEVT_PLOT1D_PARS)
73               
74    def setModel(self, target, model, tag=''):
75        """
76            Set the model and send a history event
77        """
78        # Prepare the restore event
79        self._saveCurrent(tag)
80       
81        # Now change the model
82        self.state.setModel(model)
83        evt = ModelParameters.ModelEvent(model=model, data=self.state, new=True)
84        wx.PostEvent(target, evt)
85        # Posting averager state
86        wx.PostEvent(target, AveragerParameters.AveragerStateEvent(memento=AveragerParameters.AveragerParameterMemento()))
87       
88    def _saveCurrent(self, tag=''):
89        """
90            Send a history event to capture the current state
91        """
92        #TODO: need a way to find the difference between old and new model
93        if not self.state.model == None:
94            stored_event = StateEvent(state = self.state.clone())
95           
96            # Send the history event
97            evt = history.HistoryEvent(name = self.state.model.name+'%s/%s' % (self.state.description, tag),
98                                       item = stored_event)
99            wx.PostEvent(self.target, evt)
100       
101       
102    def setSlicer(self, slicer):
103        """
104            Set the slicer
105        """
106        printEVT("StateManager.setSlicer: Slicer not implmeted")
107        self.state.slicer = slicer
108       
109    def _onEVT_STATE(self, event):
110        """
111            Restor a stored state
112            @param event: state event
113        """
114        self.state.stop()
115        self.state = event.state.clone()
116       
117        # Posting detector parameter panel state event
118        if not self.state.detector_memento == None:
119            det_event = Plotter2D.createDetectorParsEvent(qmax=self.state.detector_memento.qmax,
120                                                          npts=self.state.detector_memento.npts,
121                                                          beam=self.state.detector_memento.beam,
122                                                          zmin=self.state.detector_memento.zmin,
123                                                          zmax=self.state.detector_memento.zmax,
124                                                          sym4=self.state.detector_memento.sym4,
125                                                          info_only=True)
126        else:
127            det_event = Plotter2D.createDetectorParsEvent(qmax=None,
128                                                          npts=None,
129                                                          info_only=True)
130        printEVT("StateManager: posting detector memento")
131        wx.PostEvent(self.target, det_event)
132       
133        # Posting 1D plot parameters
134        if not self.state.pars1D_memento == None:
135            pars1D_event = Plotter1D.createPlot1DParsEvent(qmax=self.state.pars1D_memento.qmax,
136                                                           npts=self.state.pars1D_memento.npts,
137                                                           qmin=self.state.pars1D_memento.qmin,
138                                                           info_only=True)
139        else:
140            pars1D_event = Plotter1D.createPlot1DParsEvent(qmin=None,
141                                                           qmax=None,
142                                                           npts=None,
143                                                           info_only=True)
144        printEVT("StateManager: posting 1D plot pars memento")
145        wx.PostEvent(self.target, pars1D_event)
146       
147       
148        # Posting averager state
149        wx.PostEvent(self.target, AveragerParameters.AveragerStateEvent(memento=event.state.averager_memento))
150       
151        # Posting model event
152        evt = ModelParameters.ModelEvent(model=self.state.model, data=self.state, new=True)
153        wx.PostEvent(self.target, evt)
154       
155        # Posting parameter panel state event
156        evt2 = ModelParameters.ModelParameterStateEvent(memento=event.state.model_par_memento)
157        wx.PostEvent(self.target, evt2)
158       
159        printEVT("State.onEVT_STATE: history item restored: %s" % self.state.model.name)
160       
161    def _onEVT_DETECTOR(self, event):
162        config.printEVT("StateManager._onEVT_DETECTOR")
163        if event.info_only:
164            config.printEVT("   skip EVT_DETECTOR")
165            return
166       
167        event.Skip()
168        self._saveCurrent()
169       
170        # Clear current data to invoke recalculation
171        #self.state.clear_data()
172        self.state.setDetectorMemento(DetectorMemento(event.qmax, event.npts,
173                                                      zmin = event.zmin, zmax = event.zmax,
174                                                      beam = event.beam, sym4 = event.sym4))
175       
176        # Send an update event to the plotters
177        evt = ModelParameters.ModelEvent(model=self.state.model, data=self.state, new=False)
178        wx.PostEvent(self.target, evt)
179
180    def _onEVT_PLOT1D_PARS(self, event):
181        config.printEVT("StateManager._onEVT_PLOT1D_PARS")
182        if event.info_only:
183            config.printEVT("   skip EVT_PLOT1D_PARS")
184            return
185       
186        event.Skip()
187        self._saveCurrent()
188       
189        # Update the state
190        self.state.setPars1DMemento(Plotter1D.Plot1DMemento(event.qmin, 
191                                                              event.qmax, 
192                                                              event.npts))
193       
194        # Send an update event to the plotters
195        evt = ModelParameters.ModelEvent(model=self.state.model, data=self.state, new=False)
196        wx.PostEvent(self.target, evt)
197
198       
199    def _onEVT_MODEL_PARS(self, event):
200        """
201            Modify the parameters of the model and
202            fire a history event
203           
204            @param event: parameter change event
205        """
206        printEVT("State.onEVT_MODEL_PARS")
207
208        # Save the state before changing it
209        stored_event = StateEvent(state = self.state.clone())
210
211        # Post message to status bar
212        wx.PostEvent(self.target, config.StatusBarEvent(message=event.status))
213       
214        # Dispersion?
215        disp_tag = ''
216        if event.disp_changed and len(event.disp)>0:
217            if not self.state.model.__class__.__name__ == "Averager2D":
218                config.printEVT("StateMng: setting up averager")
219                new_model = Averager2D.Averager2D()
220                flag = new_model.set_model(self.state.model.clone())
221                self.state.setModel(new_model)
222            else:
223                disp_list = deepcopy(self.state.model.get_dispersity())
224                for item in disp_list:
225                    disp_tag += '/Disp[%s]=%g [%g pts]' % (item[0], item[1], item[2])
226               
227            self.state.model.set_dispersity(event.disp)
228           
229        if not event.average and \
230            self.state.model.__class__.__name__ == "Averager2D":
231            disp_list = deepcopy(self.state.model.get_dispersity())
232            if self.state.model.set_dispersity([]):
233                for item in disp_list:
234                    disp_tag += '/Disp[%s]=%g [%g pts]' % (item[0], item[1], item[2])
235       
236        # Push parameters to model
237        name = self.state.setParams(event.params)
238        self.state.setModelParMemento(event.memento)
239
240        #print str(self.state.model)
241
242        # Send an update event to the plotters
243        evt = ModelParameters.ModelEvent(model=self.state.model, data=self.state, new=False)
244        wx.PostEvent(self.target, evt)
245
246        if len(event.params)>0 or len(event.disp)>0 or event.disp_changed:     
247            # Send the history event
248            evt = history.HistoryEvent(name = name+disp_tag,
249                                       item = stored_event)
250            wx.PostEvent(self.target, evt)
251           
252            # Post chi^2 recalculation event for fit panel
253            wx.PostEvent(self.target, ChiUpdateEvent())
254           
255    def _onEVT_AVG_PARS(self, event):
256        printEVT("State._onEVT_AVG_PARS")
257
258        # Save the state before changing it
259        stored_event = StateEvent(state = self.state.clone())
260       
261        # Inspect the change to give a proper title to the
262        # history item
263        info = "Phi = OFF/THETA=ON (filename)"
264       
265        # Set averager memento to retreive the same state from history panel
266        self.state.setAveragerMemento(event.memento)
267       
268        # Flags for history event
269        phi_flag   = "OFF"
270        theta_flag = "OFF"
271                   
272        #theta_file = os.path.basename(self.theta_file_path)
273       
274        # Post message to status bar if needed
275        if not event.status == None:
276             wx.PostEvent(self.target, config.StatusBarEvent(message=event.status))
277           
278        # Check if we already have an Averager2D model
279        # When we reach this points, either we need an Averager2D
280        # or we already have one.
281        if not self.state.model.__class__.__name__ == "Averager2D":
282            model = Averager2D.Averager2D()
283            flag = model.set_model(self.state.model.clone())
284            if flag:
285                self.state.setModel(model)                       
286            else:
287                message = "Current model doesn't have theta or phi: skipping"
288                wx.PostEvent(self.target, config.StatusBarEvent(message=message))
289                return
290        else:
291            if self.state.model.phi_on:
292                phi_flag = "ON"
293            if self.state.model.theta_on:
294                theta_flag = "ON"
295           
296        # Set phi info
297        if event.phi_on:
298            if not self.state.model.setPhiFile(event.phi_file):
299                message = "Current model doesn't have phi: skipping"
300                wx.PostEvent(self.target, config.StatusBarEvent(message=message))
301        else:
302            self.state.model.setPhiFile(None)
303       
304        # Set theta info
305        if event.theta_on:
306            if not self.state.model.setThetaFile(event.theta_file):
307                message = "Current model doesn't have phi: skipping"
308                wx.PostEvent(self.target, config.StatusBarEvent(message=message))               
309        else:
310            self.state.model.setThetaFile(None)
311       
312        # Send the history event
313        hist_evt = history.HistoryEvent(name = "%s/Phi %s/Theta %s" % \
314                                        (self.state.model.name, phi_flag, theta_flag),
315                                   item = stored_event)
316        wx.PostEvent(self.target, hist_evt)
317       
318        # Send an update event to the plotters
319        evt = ModelParameters.ModelEvent(model=self.state.model, data=self.state, new=False)
320        wx.PostEvent(self.target, evt)
321
322           
323           
Note: See TracBrowser for help on using the repository browser.