source: sasview/src/sans/perspectives/fitting/batchfitpage.py @ 77cfcf0

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 77cfcf0 was b9f6d83, checked in by Mathieu Doucet <doucetm@…>, 11 years ago

Re #216 Merging wx30 branch

  • Property mode set to 100644
File size: 14.5 KB
Line 
1"""
2Batch panel
3"""
4import wx
5import wx.lib.newevent
6import math
7from sans.guiframe.events import StatusEvent   
8from sans.guiframe.events import NewPlotEvent 
9
10(Chi2UpdateEvent, EVT_CHI2_UPDATE)   = wx.lib.newevent.NewEvent()
11_BOX_WIDTH = 76
12_DATA_BOX_WIDTH = 300
13SMEAR_SIZE_L = 0.00
14SMEAR_SIZE_H = 0.00
15
16from sans.perspectives.fitting.basepage import PageInfoEvent
17from sans.models.qsmearing import smear_selection
18from sans.perspectives.fitting.fitpage import FitPage
19
20class BatchFitPage(FitPage):
21    """
22    Batch Page
23    """
24    window_name = "BatchFit"
25    window_caption  = "BatchFit"
26
27    def __init__(self, parent, color=None):
28        """
29        Initialization of the Panel
30        """
31        FitPage.__init__(self, parent, color=color)
32        self.window_name = "BatchFit"
33        self.window_caption  = "BatchFit"
34        self._set_save_flag(False)
35        self._set_bookmark_flag(False)
36       
37    def _fill_range_sizer(self):
38        """
39        Fill the sizer containing the plotting range
40        add  access to npts
41        """
42        is_2Ddata = False
43       
44        # Check if data is 2D
45        if self.data.__class__.__name__ ==  "Data2D" or \
46                        self.enable2D:
47            is_2Ddata = True
48           
49        title = "Fitting"     
50        self._get_smear_info()
51       
52        #Sizers
53        box_description_range = wx.StaticBox(self, -1, str(title))
54        boxsizer_range = wx.StaticBoxSizer(box_description_range, wx.VERTICAL)     
55        self.sizer_set_smearer = wx.BoxSizer(wx.VERTICAL)
56        #sizer_smearer = wx.BoxSizer(wx.HORIZONTAL)
57        self.sizer_new_smear = wx.BoxSizer(wx.HORIZONTAL)
58        self.sizer_set_masking = wx.BoxSizer(wx.HORIZONTAL)
59        sizer_chi2 = wx.BoxSizer(wx.VERTICAL)
60
61        sizer_fit = wx.GridSizer(2, 4, 2, 6)
62        #Fit button
63        self.btFit = wx.Button(self, wx.NewId(), 'Fit', size=(88, 25))
64        self.default_bt_colour =  self.btFit.GetDefaultAttributes()
65        self.btFit.Bind(wx.EVT_BUTTON, self._onFit, id= self.btFit.GetId())
66        self.btFit.SetToolTipString("Start fitting.")
67
68        # Update and Draw button
69        self.draw_button = wx.Button(self, wx.NewId(), 'Compute', size=(88, 24))
70        self.draw_button.Bind(wx.EVT_BUTTON, \
71                              self._onDraw,id=self.draw_button.GetId())
72        self.draw_button.SetToolTipString("Compute and Draw.") 
73        sizer_fit.Add(self.draw_button, 0, 0)
74        sizer_fit.Add(self.btFit, 0, 0) 
75        sizer_chi2.Add((-1, 5))
76        # get smear_selection
77        self.current_smearer = smear_selection( self.data, self.model )
78        boxsizer_range.Add(self.sizer_set_masking)
79         #2D data? default
80        is_2Ddata = False
81       
82        #check if it is 2D data
83        if self.data.__class__.__name__ ==  "Data2D" or \
84                        self.enable2D:
85            is_2Ddata = True
86           
87        self.sizer5.Clear(True)
88     
89        self.qmin  = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH, 20), 
90                                          style=wx.TE_PROCESS_ENTER, 
91                                    text_enter_callback = self._onQrangeEnter)
92        self.qmin.SetValue(str(self.qmin_x))
93        self.qmin.SetToolTipString("Minimun value of Q in linear scale.")
94     
95        self.qmax  = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH, 20), 
96                                          style=wx.TE_PROCESS_ENTER, 
97                                        text_enter_callback=self._onQrangeEnter)
98        self.qmax.SetValue(str(self.qmax_x))
99        self.qmax.SetToolTipString("Maximum value of Q in linear scale.")
100       
101        id = wx.NewId()
102        self.reset_qrange =wx.Button(self, id, 'Reset', size=(77, 20))
103     
104        self.reset_qrange.Bind(wx.EVT_BUTTON, self.on_reset_clicked, id=id)
105        self.reset_qrange.SetToolTipString(\
106                                    "Reset Q range to the default values")
107     
108        sizer_horizontal = wx.BoxSizer(wx.HORIZONTAL)
109        sizer = wx.GridSizer(2, 4, 2, 6)
110
111        self.btEditMask = wx.Button(self, wx.NewId(),'Editor', size=(88, 23))
112        self.btEditMask.Bind(wx.EVT_BUTTON, 
113                             self._onMask,id=self.btEditMask.GetId())
114        self.btEditMask.SetToolTipString("Edit Mask.")
115        self.EditMask_title = wx.StaticText(self, -1, ' Masking(2D)')
116
117        sizer.Add(wx.StaticText(self, -1, 'Q range'))     
118        sizer.Add(wx.StaticText(self, -1, ' Min[1/A]'))
119        sizer.Add(wx.StaticText(self, -1, ' Max[1/A]'))
120        sizer.Add(self.EditMask_title)
121 
122        sizer.Add(self.reset_qrange)   
123        sizer.Add(self.qmin)
124        sizer.Add(self.qmax)
125
126        sizer.Add(self.btEditMask)
127        boxsizer_range.Add(sizer_chi2) 
128        boxsizer_range.Add((10, 10))
129        boxsizer_range.Add(sizer)
130       
131        boxsizer_range.Add((10, 15))
132        boxsizer_range.Add(sizer_fit)
133        if is_2Ddata:
134            self.btEditMask.Enable() 
135            self.EditMask_title.Enable() 
136        else:
137            self.btEditMask.Disable() 
138            self.EditMask_title.Disable()
139
140        ## save state
141        #self.save_current_state()
142
143        self.sizer5.Add(boxsizer_range, 0, wx.EXPAND | wx.ALL, 10)
144        self.sizer5.Layout()
145       
146    def _on_select_model(self, event=None): 
147        """
148        call back for model selection
149        """ 
150       
151        self.Show(False)   
152        self._on_select_model_helper() 
153        self.set_model_param_sizer(self.model)                   
154        if self.model is None:
155            self._set_bookmark_flag(False)
156            self._keep.Enable(False)
157            self._set_save_flag(False)
158        self.enable_disp.SetValue(False)
159        self.disable_disp.SetValue(True)
160        try:
161            self.set_dispers_sizer()
162        except:
163            pass
164        self.state.structurecombobox = self.structurebox.GetCurrentSelection()
165        self.state.formfactorcombobox = self.formfactorbox.GetCurrentSelection()
166     
167        if self.model != None:
168            self._set_copy_flag(True)
169            self._set_paste_flag(True)
170            if self.data != None:
171                self._set_bookmark_flag(False)
172                self._keep.Enable(False)
173               
174            temp_smear = None
175            ## event to post model to fit to fitting plugins
176            (ModelEventbox, _) = wx.lib.newevent.NewEvent()
177         
178            ## set smearing value whether or not
179            #    the data contain the smearing info
180            evt = ModelEventbox(model=self.model, 
181                                        smearer=temp_smear, 
182                                        qmin=float(self.qmin_x),
183                                        uid=self.uid,
184                                     qmax=float(self.qmax_x)) 
185   
186            self._manager._on_model_panel(evt=evt)
187            self.mbox_description.SetLabel("Model [%s]" % str(self.model.name))
188            self.state.model = self.model.clone()
189            self.state.model.name = self.model.name
190
191           
192        if event != None:
193            ## post state to fit panel
194            new_event = PageInfoEvent(page = self)
195            wx.PostEvent(self.parent, new_event) 
196            #update list of plugins if new plugin is available
197            if self.plugin_rbutton.GetValue():
198                temp = self.parent.update_model_list()
199                if temp:
200                    self.model_list_box = temp
201                    current_val = self.formfactorbox.GetValue()
202                    pos = self.formfactorbox.GetSelection()
203                    self._show_combox_helper()
204                    self.formfactorbox.SetSelection(pos)
205                    self.formfactorbox.SetValue(current_val)
206            self._onDraw(event=None)
207        else:
208            self._draw_model()
209        self.SetupScrolling()
210        self.Show(True)   
211       
212    def _update_paramv_on_fit(self):
213        """
214        make sure that update param values just before the fitting
215        """
216        #flag for qmin qmax check values
217        flag = True
218        self.fitrange = True
219        is_modified = False
220
221        if self.model != None:           
222            ##Check the values
223            self._check_value_enter( self.fittable_param, is_modified)
224            self._check_value_enter( self.fixed_param, is_modified)
225            self._check_value_enter( self.parameters, is_modified)
226
227            # If qmin and qmax have been modified, update qmin and qmax and
228             # Here we should check whether the boundaries have been modified.
229            # If qmin and qmax have been modified, update qmin and qmax and
230            # set the is_modified flag to True
231            self.fitrange = self._validate_qrange(self.qmin, self.qmax)
232            if self.fitrange:
233                tempmin = float(self.qmin.GetValue())
234                if tempmin != self.qmin_x:
235                    self.qmin_x = tempmin
236                tempmax = float(self.qmax.GetValue())
237                if tempmax != self.qmax_x:
238                    self.qmax_x = tempmax
239                if tempmax == tempmin:
240                    flag = False   
241                #temp_smearer = None
242                if self._is_2D():
243                    # only 2D case set mask 
244                    flag = self._validate_Npts()
245                    if not flag:
246                        return flag
247            else: flag = False
248        else: 
249            flag = False
250
251        #For invalid q range, disable the mask editor and fit button, vs.   
252        if not self.fitrange:
253            #self.btFit.Disable()
254            if self._is_2D():
255                self.btEditMask.Disable()
256        else:
257            #self.btFit.Enable(True)
258            if self._is_2D() and  self.data != None:
259                self.btEditMask.Enable(True)
260
261        if not flag:
262            msg = "Cannot Plot or Fit :Must select a "
263            msg += " model or Fitting range is not valid!!!  "
264            wx.PostEvent(self.parent.parent, StatusEvent(status=msg))
265       
266        self.save_current_state()
267   
268        return flag 
269    def save_current_state(self):
270        """
271        Currently no save option implemented for batch page
272        """
273        pass 
274    def save_current_state_fit(self):
275        """
276        Currently no save option implemented for batch page
277        """
278        pass
279    def set_data(self, data):
280        """
281        reset the current data
282        """
283        #id = None
284        group_id = None
285        flag = False
286        if self.data is None and data is not None:
287            flag = True
288        if data is not None:
289            #id = data.id
290            group_id = data.group_id
291            if self.data is not None:
292                flag = (data.id != self.data.id)
293        self.data = data
294        if self.data is None:
295            data_min = ""
296            data_max = ""
297            data_name = ""
298            self._set_bookmark_flag(False)
299            self._keep.Enable(False)
300            self._set_save_flag(False)
301        else:
302            if self.model != None:
303                self._set_bookmark_flag(False)
304                self._keep.Enable(False)
305            self._set_save_flag(False)
306            self._set_preview_flag(True)
307 
308            self.formfactorbox.Enable()
309            self.structurebox.Enable()
310            data_name = self.data.name
311            #set maximum range for x in linear scale
312            if not hasattr(self.data,"data"): #Display only for 1D data fit
313                # Minimum value of data   
314                data_min = min(self.data.x)
315                # Maximum value of data 
316                data_max = max(self.data.x)
317                self.btEditMask.Disable() 
318                self.EditMask_title.Disable()
319            else:
320               
321                ## Minimum value of data
322                data_min = 0
323                x = max(math.fabs(self.data.xmin), math.fabs(self.data.xmax)) 
324                y = max(math.fabs(self.data.ymin), math.fabs(self.data.ymax))
325                ## Maximum value of data 
326                data_max = math.sqrt(x*x + y*y)
327                self.btEditMask.Enable() 
328                self.EditMask_title.Enable() 
329
330        self.dataSource.SetValue(data_name)
331        self.qmin_x = data_min
332        self.qmax_x = data_max
333        #self.minimum_q.SetValue(str(data_min))
334        #self.maximum_q.SetValue(str(data_max))
335        self.qmin.SetValue(str(data_min))
336        self.qmax.SetValue(str(data_max))
337        self.qmin.SetBackgroundColour("white")
338        self.qmax.SetBackgroundColour("white")
339        self.state.data = data
340        self.state.qmin = self.qmin_x
341        self.state.qmax = self.qmax_x
342       
343        #update model plot with new data information
344        if flag:
345            #set model view button
346            if self.data.__class__.__name__ == "Data2D":
347                self.enable2D = True
348                self.model_view.SetLabel("2D Mode")
349            else:
350                self.enable2D = False
351                self.model_view.SetLabel("1D Mode")
352               
353            self.model_view.Disable()
354           
355            wx.PostEvent(self._manager.parent, 
356                             NewPlotEvent(group_id=group_id,
357                                               action="delete"))
358            #plot the current selected data
359            wx.PostEvent(self._manager.parent, NewPlotEvent(plot=self.data, 
360                                                    title=str(self.data.title)))
361            self._manager.store_data(uid=self.uid, data=data,
362                                     data_list=self.data_list,
363                                      caption=self.window_name)
364            self._draw_model()
365   
366
367       
368class BGTextCtrl(wx.TextCtrl):
369    """
370    Text control used to display outputs.
371    No editing allowed. The background is
372    grayed out. User can't select text.
373    """
374    def __init__(self, *args, **kwds):
375        wx.TextCtrl.__init__(self, *args, **kwds)
376        self.SetEditable(False)
377        self.SetBackgroundColour(self.GetParent().parent.GetBackgroundColour())
378       
379        # Bind to mouse event to avoid text highlighting
380        # The event will be skipped once the call-back
381        # is called.
382        self.Bind(wx.EVT_MOUSE_EVENTS, self._click)
383       
384    def _click(self, event):
385        """
386        Prevent further handling of the mouse event
387        by not calling Skip().
388        """ 
389        pass
390 
Note: See TracBrowser for help on using the repository browser.