""" Batch panel """ import wx import wx.lib.newevent import math from sas.guiframe.events import StatusEvent from sas.guiframe.events import NewPlotEvent (Chi2UpdateEvent, EVT_CHI2_UPDATE) = wx.lib.newevent.NewEvent() _BOX_WIDTH = 76 _DATA_BOX_WIDTH = 300 SMEAR_SIZE_L = 0.00 SMEAR_SIZE_H = 0.00 from sas.perspectives.fitting.basepage import PageInfoEvent from sas.models.qsmearing import smear_selection from sas.perspectives.fitting.fitpage import FitPage class BatchFitPage(FitPage): """ Batch Page """ window_name = "BatchFit" window_caption = "BatchFit" def __init__(self, parent, color=None): """ Initialization of the Panel """ FitPage.__init__(self, parent, color=color) self.window_name = "BatchFit" self.window_caption = "BatchFit" self._set_save_flag(False) self._set_bookmark_flag(False) def _fill_range_sizer(self): """ Fill the sizer containing the plotting range add access to npts """ is_2Ddata = False # Check if data is 2D if self.data.__class__.__name__ == "Data2D" or \ self.enable2D: is_2Ddata = True title = "Fitting" self._get_smear_info() #Sizers box_description_range = wx.StaticBox(self, -1, str(title)) boxsizer_range = wx.StaticBoxSizer(box_description_range, wx.VERTICAL) self.sizer_set_smearer = wx.BoxSizer(wx.VERTICAL) #sizer_smearer = wx.BoxSizer(wx.HORIZONTAL) self.sizer_new_smear = wx.BoxSizer(wx.HORIZONTAL) self.sizer_set_masking = wx.BoxSizer(wx.HORIZONTAL) sizer_chi2 = wx.BoxSizer(wx.VERTICAL) sizer_fit = wx.GridSizer(2, 4, 2, 6) #Fit button self.btFit = wx.Button(self, wx.NewId(), 'Fit', size=(88, 25)) self.default_bt_colour = self.btFit.GetDefaultAttributes() self.btFit.Bind(wx.EVT_BUTTON, self._onFit, id= self.btFit.GetId()) self.btFit.SetToolTipString("Start fitting.") # Update and Draw button self.draw_button = wx.Button(self, wx.NewId(), 'Compute', size=(88, 24)) self.draw_button.Bind(wx.EVT_BUTTON, \ self._onDraw,id=self.draw_button.GetId()) self.draw_button.SetToolTipString("Compute and Draw.") sizer_fit.Add(self.draw_button, 0, 0) sizer_fit.Add(self.btFit, 0, 0) sizer_chi2.Add((-1, 5)) # get smear_selection self.current_smearer = smear_selection( self.data, self.model ) boxsizer_range.Add(self.sizer_set_masking) #2D data? default is_2Ddata = False #check if it is 2D data if self.data.__class__.__name__ == "Data2D" or \ self.enable2D: is_2Ddata = True self.sizer5.Clear(True) self.qmin = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH, 20), style=wx.TE_PROCESS_ENTER, text_enter_callback = self._onQrangeEnter) self.qmin.SetValue(str(self.qmin_x)) self.qmin.SetToolTipString("Minimun value of Q in linear scale.") self.qmax = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH, 20), style=wx.TE_PROCESS_ENTER, text_enter_callback=self._onQrangeEnter) self.qmax.SetValue(str(self.qmax_x)) self.qmax.SetToolTipString("Maximum value of Q in linear scale.") id = wx.NewId() self.reset_qrange =wx.Button(self, id, 'Reset', size=(77, 20)) self.reset_qrange.Bind(wx.EVT_BUTTON, self.on_reset_clicked, id=id) self.reset_qrange.SetToolTipString(\ "Reset Q range to the default values") sizer_horizontal = wx.BoxSizer(wx.HORIZONTAL) sizer = wx.GridSizer(2, 4, 2, 6) self.btEditMask = wx.Button(self, wx.NewId(),'Editor', size=(88, 23)) self.btEditMask.Bind(wx.EVT_BUTTON, self._onMask,id=self.btEditMask.GetId()) self.btEditMask.SetToolTipString("Edit Mask.") self.EditMask_title = wx.StaticText(self, -1, ' Masking(2D)') sizer.Add(wx.StaticText(self, -1, 'Q range')) sizer.Add(wx.StaticText(self, -1, ' Min[1/A]')) sizer.Add(wx.StaticText(self, -1, ' Max[1/A]')) sizer.Add(self.EditMask_title) sizer.Add(self.reset_qrange) sizer.Add(self.qmin) sizer.Add(self.qmax) sizer.Add(self.btEditMask) boxsizer_range.Add(sizer_chi2) boxsizer_range.Add((10, 10)) boxsizer_range.Add(sizer) boxsizer_range.Add((10, 15)) boxsizer_range.Add(sizer_fit) if is_2Ddata: self.btEditMask.Enable() self.EditMask_title.Enable() else: self.btEditMask.Disable() self.EditMask_title.Disable() ## save state #self.save_current_state() self.sizer5.Add(boxsizer_range, 0, wx.EXPAND | wx.ALL, 10) self.sizer5.Layout() def _on_select_model(self, event=None): """ call back for model selection """ self.Show(False) self._on_select_model_helper() self.set_model_param_sizer(self.model) if self.model is None: self._set_bookmark_flag(False) self._keep.Enable(False) self._set_save_flag(False) self.enable_disp.SetValue(False) self.disable_disp.SetValue(True) try: self.set_dispers_sizer() except: pass self.state.structurecombobox = self.structurebox.GetCurrentSelection() self.state.formfactorcombobox = self.formfactorbox.GetCurrentSelection() if self.model != None: self._set_copy_flag(True) self._set_paste_flag(True) if self.data != None: self._set_bookmark_flag(False) self._keep.Enable(False) temp_smear = None ## event to post model to fit to fitting plugins (ModelEventbox, _) = wx.lib.newevent.NewEvent() ## set smearing value whether or not # the data contain the smearing info evt = ModelEventbox(model=self.model, smearer=temp_smear, qmin=float(self.qmin_x), uid=self.uid, qmax=float(self.qmax_x)) self._manager._on_model_panel(evt=evt) self.mbox_description.SetLabel("Model [%s]" % str(self.model.name)) self.state.model = self.model.clone() self.state.model.name = self.model.name if event != None: ## post state to fit panel new_event = PageInfoEvent(page = self) wx.PostEvent(self.parent, new_event) #update list of plugins if new plugin is available if self.plugin_rbutton.GetValue(): temp = self.parent.update_model_list() if temp: self.model_list_box = temp current_val = self.formfactorbox.GetValue() pos = self.formfactorbox.GetSelection() self._show_combox_helper() self.formfactorbox.SetSelection(pos) self.formfactorbox.SetValue(current_val) self._onDraw(event=None) else: self._draw_model() self.SetupScrolling() self.Show(True) def _update_paramv_on_fit(self): """ make sure that update param values just before the fitting """ #flag for qmin qmax check values flag = True self.fitrange = True is_modified = False if self.model != None: ##Check the values self._check_value_enter( self.fittable_param, is_modified) self._check_value_enter( self.fixed_param, is_modified) self._check_value_enter( self.parameters, is_modified) # If qmin and qmax have been modified, update qmin and qmax and # Here we should check whether the boundaries have been modified. # If qmin and qmax have been modified, update qmin and qmax and # set the is_modified flag to True self.fitrange = self._validate_qrange(self.qmin, self.qmax) if self.fitrange: tempmin = float(self.qmin.GetValue()) if tempmin != self.qmin_x: self.qmin_x = tempmin tempmax = float(self.qmax.GetValue()) if tempmax != self.qmax_x: self.qmax_x = tempmax if tempmax == tempmin: flag = False #temp_smearer = None if self._is_2D(): # only 2D case set mask flag = self._validate_Npts() if not flag: return flag else: flag = False else: flag = False #For invalid q range, disable the mask editor and fit button, vs. if not self.fitrange: #self.btFit.Disable() if self._is_2D(): self.btEditMask.Disable() else: #self.btFit.Enable(True) if self._is_2D() and self.data != None: self.btEditMask.Enable(True) if not flag: msg = "Cannot Plot or Fit :Must select a " msg += " model or Fitting range is not valid!!! " wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) self.save_current_state() return flag def save_current_state(self): """ Currently no save option implemented for batch page """ pass def save_current_state_fit(self): """ Currently no save option implemented for batch page """ pass def set_data(self, data): """ reset the current data """ #id = None group_id = None flag = False if self.data is None and data is not None: flag = True if data is not None: #id = data.id group_id = data.group_id if self.data is not None: flag = (data.id != self.data.id) self.data = data if self.data is None: data_min = "" data_max = "" data_name = "" self._set_bookmark_flag(False) self._keep.Enable(False) self._set_save_flag(False) else: if self.model != None: self._set_bookmark_flag(False) self._keep.Enable(False) self._set_save_flag(False) self._set_preview_flag(True) self.formfactorbox.Enable() self.structurebox.Enable() data_name = self.data.name #set maximum range for x in linear scale if not hasattr(self.data,"data"): #Display only for 1D data fit # Minimum value of data data_min = min(self.data.x) # Maximum value of data data_max = max(self.data.x) self.btEditMask.Disable() self.EditMask_title.Disable() else: ## Minimum value of data data_min = 0 x = max(math.fabs(self.data.xmin), math.fabs(self.data.xmax)) y = max(math.fabs(self.data.ymin), math.fabs(self.data.ymax)) ## Maximum value of data data_max = math.sqrt(x*x + y*y) self.btEditMask.Enable() self.EditMask_title.Enable() self.dataSource.SetValue(data_name) self.qmin_x = data_min self.qmax_x = data_max #self.minimum_q.SetValue(str(data_min)) #self.maximum_q.SetValue(str(data_max)) self.qmin.SetValue(str(data_min)) self.qmax.SetValue(str(data_max)) self.qmin.SetBackgroundColour("white") self.qmax.SetBackgroundColour("white") self.state.data = data self.state.qmin = self.qmin_x self.state.qmax = self.qmax_x #update model plot with new data information if flag: #set model view button if self.data.__class__.__name__ == "Data2D": self.enable2D = True self.model_view.SetLabel("2D Mode") else: self.enable2D = False self.model_view.SetLabel("1D Mode") self.model_view.Disable() wx.PostEvent(self._manager.parent, NewPlotEvent(group_id=group_id, action="delete")) #plot the current selected data wx.PostEvent(self._manager.parent, NewPlotEvent(plot=self.data, title=str(self.data.title))) self._manager.store_data(uid=self.uid, data=data, data_list=self.data_list, caption=self.window_name) self._draw_model() class BGTextCtrl(wx.TextCtrl): """ Text control used to display outputs. No editing allowed. The background is grayed out. User can't select text. """ def __init__(self, *args, **kwds): wx.TextCtrl.__init__(self, *args, **kwds) self.SetEditable(False) self.SetBackgroundColour(self.GetParent().parent.GetBackgroundColour()) # Bind to mouse event to avoid text highlighting # The event will be skipped once the call-back # is called. self.Bind(wx.EVT_MOUSE_EVENTS, self._click) def _click(self, event): """ Prevent further handling of the mouse event by not calling Skip(). """ pass