source: sasview/src/sas/sasgui/perspectives/fitting/batchfitpage.py @ f4161f7a

magnetic_scattrelease-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249unittest-saveload
Last change on this file since f4161f7a was 50fcb09, checked in by Paul Kienzle <pkienzle@…>, 7 years ago

move qsmearing to fit package

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