source: sasview/sansview/perspectives/fitting/state.py @ 2a8fac1

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

help dialog window changed to frame

  • Property mode set to 100644
File size: 8.3 KB
Line 
1"""
2    Object to manage the state of the application
3"""
4
5#TODO: use both CPUs and break the calculations in two threads
6#TODO: stop threads before starting a new one
7
8import wx
9import wx.lib.newevent
10
11#import ModelParameters
12#import history
13import modelData
14from model_thread import Calc2D, Calc1D, Calc2D_4fold, Calc2D_all
15from copy import deepcopy
16
17#TODO: State should report back to StateManager instead
18#    of firing these events itself
19(Refresh2DEvent, EVT_2DREFRESH) = wx.lib.newevent.NewEvent()
20(Refresh1DEvent, EVT_1DREFRESH) = wx.lib.newevent.NewEvent()
21
22# Debug printout
23#from config import printEVT
24
25
26
27class State:
28   
29    def __init__(self, target=None,data=None, model=None, slicer=None, panel=None):
30        self.target = target
31        self.model  = model
32        self.data   = data
33        self.type_panel= None
34        self.disp_list = []
35        self.manager = None
36        self.parent  = parent
37        self.event_owner = None
38        self.modelbox = wx.ComboBox(self, -1)
39         # preview selected model name
40        self.prevmodel_name=name
41        #print "model view prev_model",name
42        self.modelbox.SetValue(self.prevmodel_name)
43        #enable model 2D draw
44        self.enable2D= False
45         ## Q range
46        self.qmin_x= 0.001
47        self.qmax_x= 0.1
48        self.num_points= 100
49        self.parameters=[]
50        self.fixed_param=[]
51        self.fittable_param=[]
52        #contains link between a model and selected parameters to fit
53        self.param_toFit=[]
54       
55        #dictionary of model name and model class
56        self.model_list_box={}
57        #Draw initial panel
58        self.enable_disp= None
59        self.disable_disp=None   
60           
61        if panel !=None:
62            self.panel= panel
63           
64       
65       
66        self.slicer = slicer
67        self.model_par_memento = None
68        self.detector_memento = None
69        self.averager_memento = None
70        self.pars1D_memento   = None
71       
72        # Keep the latest data
73        self._data_2D = None
74        self._data_1D = None
75        # The following should disappear
76        self.qmax = None
77        self.x_1D = None
78       
79        # Threads
80        self.active = True
81        self.calc_thread_2D = None
82        self.calc_thread_1D = None
83       
84        # Info for history
85        self.description = ''
86    def clone_panel(self):
87        obj          = State(self.target, self.model.clone(),self.panel)
88        obj.data = deepcopy(self.data)
89       
90       
91       
92       
93    def clone(self):
94        obj          = State(self.target, self.model.clone(), self.slicer)
95        obj._data_1D = deepcopy(self._data_1D)
96        obj._data_2D = deepcopy(self._data_2D)
97        obj.qmax     = deepcopy(self.qmax)
98        obj.x_1D     = deepcopy(self.x_1D)
99        obj.model_par_memento = deepcopy(self.model_par_memento)
100        obj.detector_memento = deepcopy(self.detector_memento)
101        obj.averager_memento = deepcopy(self.averager_memento)
102        obj.description = self.description
103        return obj
104       
105    def clear_data(self):
106        self._data_1D = None
107        self._data_2D = None
108       
109    def stop(self):
110        self.active = False
111        if self.calc_thread_1D != None and self.calc_thread_1D.isrunning():
112            self.calc_thread_1D.stop()
113        if self.calc_thread_2D != None and self.calc_thread_2D.isrunning():
114            self.calc_thread_2D.stop()
115       
116    def setModelParMemento(self, memento):
117        self.model_par_memento = memento
118       
119    def setDetectorMemento(self, memento):
120        self.clear_data()
121        # Change description
122        self.description = '%s' % memento.toString(self.detector_memento)
123        self.detector_memento = memento
124       
125    def setPars1DMemento(self, memento):
126        self.clear_data()
127        # Change description
128        self.description = '%s' % memento.toString(self.pars1D_memento)
129        self.pars1D_memento = memento
130       
131    def setAveragerMemento(self, memento):
132        self.clear_data()
133        self.averager_memento = memento
134       
135    def setModel(self, model):
136        """
137            Set the model and send a history event
138        """
139        # Clean the data to invoke recalc
140        self._data_1D = None
141        self._data_2D = None
142       
143        # Set the model
144        self.model = model
145       
146        self.description = ''
147       
148        return str(self.model.name)
149       
150    def setParams(self, params):
151        """
152            Update parameters and return a name
153            that represents the change (key)
154        """
155        # Clean the data to invoke recalc
156        self._data_1D = None
157        self._data_2D = None
158
159        # Compose string to summarize change       
160        name = self.model.name
161       
162        # Identify and perform changes
163        for item in params:
164            name += "/%s=%-5.5g" % (item, self.model.getParam(item))
165            self.model.setParam(item, params[item])
166       
167        return name
168
169    def setSlicer(self, slicer):
170        self.slicer = slicer
171       
172    def get_data_1d(self, x):
173        """
174            Calculate the data
175            @param min: minimum q-value
176            @param max: maximum q-value
177        """
178       
179        printEVT("State.get_data_1d")
180        if not self.model:
181            return
182       
183        if self._data_1D == None:
184            self.x_1D = deepcopy(x)
185            if self.calc_thread_1D != None and self.calc_thread_1D.isrunning():
186                self.calc_thread_1D.stop()
187               
188            self.calc_thread_1D = Calc1D(x, self.model.clone(), 
189                                completefn=self.complete1D,
190                                updatefn=self.update1D)
191            self.calc_thread_1D.queue()
192            self.calc_thread_1D.ready(2.5)
193        else:
194            printEVT("Dispatch 1D non-recalc data") 
195            wx.PostEvent(self.target, Refresh1DEvent(name=self.model.name, x = self.x_1D,
196                                                     output=deepcopy(self._data_1D)))
197         
198   
199    def get_data_2d(self, max, x, y):
200        """
201            Calculate 2D data
202            @param max: maximum q-value
203        """
204        if not self.model:
205            return
206       
207        if self._data_2D == None:
208            self.qmax = max
209            if self.calc_thread_2D != None and self.calc_thread_2D.isrunning():
210                self.calc_thread_2D.stop()
211               
212            if self.detector_memento == None or self.detector_memento.sym4 == False:   
213                self.calc_thread_2D = Calc2D(x, y, self.model.clone(), 
214                                    completefn=self.complete2D,
215                                    updatefn=self.update2D,
216                                    yieldtime=0.0)
217            else:
218                self.calc_thread_2D = Calc2D_4fold(x, y, self.model.clone(), 
219                                    completefn=self.complete2D,
220                                    updatefn=self.update2D,
221                                    yieldtime=0.0)
222               
223            self.calc_thread_2D.queue()
224            self.calc_thread_2D.ready(2.5)
225        else:
226            print
227            #printEVT("Dispatch 2D non-recalc data")
228            #wx.PostEvent(self.target, Refresh2DEvent(output=deepcopy(self._data_2D),
229            #                                        qmax=self.qmax))
230           
231             
232    def update2D(self, output):
233        printEVT("State.updated2D")
234        if self.active:
235            #self._data_2D = output
236            self._data_2D = deepcopy(output)
237            wx.PostEvent(self.target, Refresh2DEvent(output=deepcopy(self._data_2D),
238                                                qmax=self.qmax))
239   
240    def complete2D(self, output, elapsed):
241        printEVT("%s: Calc 2D complete in %g sec" % (self.model.name, elapsed)) 
242        if self.active:
243            self._data_2D = deepcopy(output)
244            wx.PostEvent(self.target, Refresh2DEvent(output=deepcopy(self._data_2D),
245                                                qmax=self.qmax))
246        else:
247            printEVT("Active = False!")
248
249    def update1D(self, output):
250        pass
251   
252    def complete1D(self, output, elapsed):
253        printEVT("Calc 1D complete in %g sec" % elapsed) 
254        self._data_1D = deepcopy(output)
255        wx.PostEvent(self.target, Refresh1DEvent(name=self.model.name, x = self.x_1D,
256                                                 output=deepcopy(self._data_1D)))
257
258   
Note: See TracBrowser for help on using the repository browser.