1 | |
---|
2 | |
---|
3 | import sys |
---|
4 | import wx |
---|
5 | import wx.lib.newevent |
---|
6 | import numpy |
---|
7 | import copy |
---|
8 | import math |
---|
9 | import time |
---|
10 | from sans.models.dispersion_models import ArrayDispersion, GaussianDispersion |
---|
11 | from sans.dataloader.data_info import Data1D |
---|
12 | from sans.guiframe.events import StatusEvent |
---|
13 | from sans.guiframe.events import NewPlotEvent |
---|
14 | from sans.guiframe.utils import format_number,check_float |
---|
15 | |
---|
16 | (Chi2UpdateEvent, EVT_CHI2_UPDATE) = wx.lib.newevent.NewEvent() |
---|
17 | _BOX_WIDTH = 76 |
---|
18 | _DATA_BOX_WIDTH = 300 |
---|
19 | SMEAR_SIZE_L = 0.00 |
---|
20 | SMEAR_SIZE_H = 0.00 |
---|
21 | |
---|
22 | import basepage |
---|
23 | from basepage import BasicPage |
---|
24 | from basepage import PageInfoEvent |
---|
25 | from sans.models.qsmearing import smear_selection |
---|
26 | from fitpage import FitPage |
---|
27 | |
---|
28 | class BatchFitPage(FitPage): |
---|
29 | window_name = "BatchFit" |
---|
30 | window_caption = "BatchFit" |
---|
31 | |
---|
32 | def __init__(self,parent, color='rand'): |
---|
33 | """ |
---|
34 | Initialization of the Panel |
---|
35 | """ |
---|
36 | FitPage.__init__(self, parent, color=color) |
---|
37 | self.window_name = "BatchFit" |
---|
38 | self.window_caption = "BatchFit" |
---|
39 | self._set_save_flag(False) |
---|
40 | self._set_bookmark_flag(False) |
---|
41 | |
---|
42 | def _fill_range_sizer(self): |
---|
43 | """ |
---|
44 | Fill the sizer containing the plotting range |
---|
45 | add access to npts |
---|
46 | """ |
---|
47 | is_2Ddata = False |
---|
48 | |
---|
49 | # Check if data is 2D |
---|
50 | if self.data.__class__.__name__ == "Data2D" or \ |
---|
51 | self.enable2D: |
---|
52 | is_2Ddata = True |
---|
53 | |
---|
54 | title = "Fitting" |
---|
55 | #smear messages & titles |
---|
56 | smear_message_none = "No smearing is selected..." |
---|
57 | smear_message_dqdata = "The dQ data is being used for smearing..." |
---|
58 | smear_message_2d = "Higher accuracy is very time-expensive. Use it with care..." |
---|
59 | smear_message_new_ssmear = "Please enter only the value of interest to customize smearing..." |
---|
60 | smear_message_new_psmear = "Please enter both; the dQ will be generated by interpolation..." |
---|
61 | smear_message_2d_x_title = "<dQp>[1/A]:" |
---|
62 | smear_message_2d_y_title = "<dQs>[1/A]:" |
---|
63 | smear_message_pinhole_min_title = "dQ_low[1/A]:" |
---|
64 | smear_message_pinhole_max_title = "dQ_high[1/A]:" |
---|
65 | smear_message_slit_height_title = "Slit height[1/A]:" |
---|
66 | smear_message_slit_width_title = "Slit width[1/A]:" |
---|
67 | |
---|
68 | self._get_smear_info() |
---|
69 | |
---|
70 | #Sizers |
---|
71 | box_description_range = wx.StaticBox(self, -1,str(title)) |
---|
72 | boxsizer_range = wx.StaticBoxSizer(box_description_range, wx.VERTICAL) |
---|
73 | self.sizer_set_smearer = wx.BoxSizer(wx.VERTICAL) |
---|
74 | sizer_smearer = wx.BoxSizer(wx.HORIZONTAL) |
---|
75 | self.sizer_new_smear= wx.BoxSizer(wx.HORIZONTAL) |
---|
76 | self.sizer_set_masking = wx.BoxSizer(wx.HORIZONTAL) |
---|
77 | sizer_chi2 = wx.BoxSizer(wx.VERTICAL) |
---|
78 | """ |
---|
79 | smear_set_box= wx.StaticBox(self, -1,'Set Instrumental Smearing') |
---|
80 | sizer_smearer_box = wx.StaticBoxSizer(smear_set_box, wx.HORIZONTAL) |
---|
81 | sizer_smearer_box.SetMinSize((_DATA_BOX_WIDTH,85)) |
---|
82 | """ |
---|
83 | sizer_fit = wx.GridSizer(2, 4, 2, 6) |
---|
84 | """ |
---|
85 | # combobox for smear2d accuracy selection |
---|
86 | self.smear_accuracy = wx.ComboBox(self, -1,size=(50,-1),style=wx.CB_READONLY) |
---|
87 | self._set_accuracy_list() |
---|
88 | self.smear_accuracy.SetValue(self.smear2d_accuracy) |
---|
89 | self.smear_accuracy.SetSelection(0) |
---|
90 | self.smear_accuracy.SetToolTipString("'Higher' uses more Gaussian points for smearing computation.") |
---|
91 | |
---|
92 | wx.EVT_COMBOBOX(self.smear_accuracy,-1, self._on_select_accuracy) |
---|
93 | """ |
---|
94 | #Fit button |
---|
95 | self.btFit = wx.Button(self,wx.NewId(),'Fit', size=(88,25)) |
---|
96 | self.default_bt_colour = self.btFit.GetDefaultAttributes() |
---|
97 | self.btFit.Bind(wx.EVT_BUTTON, self._onFit,id= self.btFit.GetId()) |
---|
98 | self.btFit.SetToolTipString("Start fitting.") |
---|
99 | """ |
---|
100 | #textcntrl for custom resolution |
---|
101 | self.smear_pinhole_max = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-25,20),style=wx.TE_PROCESS_ENTER, |
---|
102 | text_enter_callback = self.onPinholeSmear) |
---|
103 | self.smear_pinhole_min = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-25,20),style=wx.TE_PROCESS_ENTER, |
---|
104 | text_enter_callback = self.onPinholeSmear) |
---|
105 | self.smear_slit_height= self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-25,20),style=wx.TE_PROCESS_ENTER, |
---|
106 | text_enter_callback = self.onSlitSmear) |
---|
107 | self.smear_slit_width = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-25,20),style=wx.TE_PROCESS_ENTER, |
---|
108 | text_enter_callback = self.onSlitSmear) |
---|
109 | |
---|
110 | ## smear |
---|
111 | self.smear_data_left= BGTextCtrl(self, -1, size=(_BOX_WIDTH-25,20), style=0) |
---|
112 | self.smear_data_left.SetValue(str(self.dq_l)) |
---|
113 | self.smear_data_right = BGTextCtrl(self, -1, size=(_BOX_WIDTH-25,20), style=0) |
---|
114 | self.smear_data_right.SetValue(str(self.dq_r)) |
---|
115 | |
---|
116 | #set default values for smear |
---|
117 | self.smear_pinhole_max.SetValue(str(self.dx_max)) |
---|
118 | self.smear_pinhole_min.SetValue(str(self.dx_min)) |
---|
119 | self.smear_slit_height.SetValue(str(self.dxl)) |
---|
120 | self.smear_slit_width.SetValue(str(self.dxw)) |
---|
121 | |
---|
122 | #Filling the sizer containing instruments smearing info. |
---|
123 | self.disable_smearer = wx.RadioButton(self, -1, 'None', style=wx.RB_GROUP) |
---|
124 | self.enable_smearer = wx.RadioButton(self, -1, 'Use dQ Data') |
---|
125 | #self.enable_smearer.SetToolTipString("Click to use the loaded dQ data for smearing.") |
---|
126 | self.pinhole_smearer = wx.RadioButton(self, -1, 'Custom Pinhole Smear') |
---|
127 | #self.pinhole_smearer.SetToolTipString("Click to input custom resolution for pinhole smearing.") |
---|
128 | self.slit_smearer = wx.RadioButton(self, -1, 'Custom Slit Smear') |
---|
129 | #self.slit_smearer.SetToolTipString("Click to input custom resolution for slit smearing.") |
---|
130 | self.Bind(wx.EVT_RADIOBUTTON, self.onSmear, id=self.disable_smearer.GetId()) |
---|
131 | self.Bind(wx.EVT_RADIOBUTTON, self.onSmear, id=self.enable_smearer.GetId()) |
---|
132 | self.Bind(wx.EVT_RADIOBUTTON, self.onPinholeSmear, id=self.pinhole_smearer.GetId()) |
---|
133 | self.Bind(wx.EVT_RADIOBUTTON, self.onSlitSmear, id=self.slit_smearer.GetId()) |
---|
134 | self.disable_smearer.SetValue(True) |
---|
135 | |
---|
136 | # add 4 types of smearing to the sizer |
---|
137 | sizer_smearer.Add( self.disable_smearer,0, wx.LEFT, 10) |
---|
138 | sizer_smearer.Add((10,10)) |
---|
139 | sizer_smearer.Add( self.enable_smearer) |
---|
140 | sizer_smearer.Add((10,10)) |
---|
141 | sizer_smearer.Add( self.pinhole_smearer ) |
---|
142 | sizer_smearer.Add((10,10)) |
---|
143 | sizer_smearer.Add( self.slit_smearer ) |
---|
144 | sizer_smearer.Add((10,10)) |
---|
145 | """ |
---|
146 | """ |
---|
147 | # StaticText for chi2, N(for fitting), Npts |
---|
148 | self.tcChi = BGTextCtrl(self, -1, "-", size=(75,20), style=0) |
---|
149 | self.tcChi.SetToolTipString("Chi2/Npts(Fit)") |
---|
150 | self.Npts_fit = BGTextCtrl(self, -1, "-", size=(75,20), style=0) |
---|
151 | self.Npts_fit.SetToolTipString(\ |
---|
152 | " Npts : number of points selected for fitting") |
---|
153 | self.Npts_total = self.ModelTextCtrl(self, -1, size=(_BOX_WIDTH, 20), |
---|
154 | style=wx.TE_PROCESS_ENTER, |
---|
155 | text_enter_callback=self._onQrangeEnter) |
---|
156 | self.Npts_total.SetValue(format_number(self.npts_x)) |
---|
157 | self.Npts_total.SetToolTipString(\ |
---|
158 | " Total Npts : total number of data points") |
---|
159 | """ |
---|
160 | # Update and Draw button |
---|
161 | self.draw_button = wx.Button(self,wx.NewId(),'Compute', size=(88,24)) |
---|
162 | self.draw_button.Bind(wx.EVT_BUTTON, \ |
---|
163 | self._onDraw,id= self.draw_button.GetId()) |
---|
164 | self.draw_button.SetToolTipString("Compute and Draw.") |
---|
165 | """ |
---|
166 | box_description_1= wx.StaticText(self, -1,' Chi2/Npts') |
---|
167 | box_description_2= wx.StaticText(self, -1,'Npts(Fit)') |
---|
168 | box_description_3= wx.StaticText(self, -1,'Total Npts') |
---|
169 | box_description_3.SetToolTipString( \ |
---|
170 | " Total Npts : total number of data points") |
---|
171 | #box_description_4= wx.StaticText(self, -1,' ') |
---|
172 | """ |
---|
173 | |
---|
174 | """ |
---|
175 | sizer_fit.Add(box_description_1,0,0) |
---|
176 | sizer_fit.Add(box_description_2,0,0) |
---|
177 | sizer_fit.Add(box_description_3,0,0) |
---|
178 | """ |
---|
179 | sizer_fit.Add(self.draw_button,0,0) |
---|
180 | """ |
---|
181 | sizer_fit.Add(self.tcChi,0,0) |
---|
182 | sizer_fit.Add(self.Npts_fit ,0,0) |
---|
183 | sizer_fit.Add(self.Npts_total,0,0) |
---|
184 | """ |
---|
185 | sizer_fit.Add(self.btFit,0,0) |
---|
186 | """ |
---|
187 | self.smear_description_none = wx.StaticText(self, -1, smear_message_none , style=wx.ALIGN_LEFT) |
---|
188 | self.smear_description_dqdata = wx.StaticText(self, -1, smear_message_dqdata , style=wx.ALIGN_LEFT) |
---|
189 | self.smear_description_type = wx.StaticText(self, -1, "Type:" , style=wx.ALIGN_LEFT) |
---|
190 | self.smear_description_accuracy_type = wx.StaticText(self, -1, "Accuracy:" , style=wx.ALIGN_LEFT) |
---|
191 | self.smear_description_smear_type = BGTextCtrl(self, -1, size=(57,20), style=0) |
---|
192 | self.smear_description_smear_type.SetValue(str(self.dq_l)) |
---|
193 | self.SetBackgroundColour(self.GetParent().GetBackgroundColour()) |
---|
194 | self.smear_description_2d = wx.StaticText(self, -1, smear_message_2d , style=wx.ALIGN_LEFT) |
---|
195 | self.smear_message_new_s = wx.StaticText(self, -1, smear_message_new_ssmear , style=wx.ALIGN_LEFT) |
---|
196 | self.smear_message_new_p = wx.StaticText(self, -1, smear_message_new_psmear , style=wx.ALIGN_LEFT) |
---|
197 | self.smear_description_2d_x = wx.StaticText(self, -1, smear_message_2d_x_title , style=wx.ALIGN_LEFT) |
---|
198 | self.smear_description_2d_x.SetToolTipString(" dQp(parallel) in q_r direction.") |
---|
199 | self.smear_description_2d_y = wx.StaticText(self, -1, smear_message_2d_y_title , style=wx.ALIGN_LEFT) |
---|
200 | self.smear_description_2d_y.SetToolTipString(" dQs(perpendicular) in q_phi direction.") |
---|
201 | self.smear_description_pin_min = wx.StaticText(self, -1, smear_message_pinhole_min_title , style=wx.ALIGN_LEFT) |
---|
202 | self.smear_description_pin_max = wx.StaticText(self, -1, smear_message_pinhole_max_title , style=wx.ALIGN_LEFT) |
---|
203 | self.smear_description_slit_height = wx.StaticText(self, -1, smear_message_slit_height_title , style=wx.ALIGN_LEFT) |
---|
204 | self.smear_description_slit_width = wx.StaticText(self, -1, smear_message_slit_width_title , style=wx.ALIGN_LEFT) |
---|
205 | """ |
---|
206 | #arrange sizers |
---|
207 | #boxsizer1.Add( self.tcChi ) |
---|
208 | """ |
---|
209 | self.sizer_set_smearer.Add(sizer_smearer ) |
---|
210 | self.sizer_set_smearer.Add((10,10)) |
---|
211 | self.sizer_set_smearer.Add( self.smear_description_none,0, wx.CENTER, 10 ) |
---|
212 | self.sizer_set_smearer.Add( self.smear_description_dqdata,0, wx.CENTER, 10 ) |
---|
213 | self.sizer_set_smearer.Add( self.smear_description_2d,0, wx.CENTER, 10 ) |
---|
214 | self.sizer_new_smear.Add( self.smear_description_type,0, wx.CENTER, 10 ) |
---|
215 | self.sizer_new_smear.Add( self.smear_description_accuracy_type,0, wx.CENTER, 10 ) |
---|
216 | self.sizer_new_smear.Add( self.smear_accuracy ) |
---|
217 | self.sizer_new_smear.Add( self.smear_description_smear_type,0, wx.CENTER, 10 ) |
---|
218 | self.sizer_new_smear.Add((15,-1)) |
---|
219 | self.sizer_new_smear.Add( self.smear_description_2d_x,0, wx.CENTER, 10 ) |
---|
220 | self.sizer_new_smear.Add( self.smear_description_pin_min,0, wx.CENTER, 10 ) |
---|
221 | self.sizer_new_smear.Add( self.smear_description_slit_height,0, wx.CENTER, 10 ) |
---|
222 | |
---|
223 | self.sizer_new_smear.Add( self.smear_pinhole_min,0, wx.CENTER, 10 ) |
---|
224 | self.sizer_new_smear.Add( self.smear_slit_height,0, wx.CENTER, 10 ) |
---|
225 | self.sizer_new_smear.Add( self.smear_data_left,0, wx.CENTER, 10 ) |
---|
226 | self.sizer_new_smear.Add((20,-1)) |
---|
227 | self.sizer_new_smear.Add( self.smear_description_2d_y,0, wx.CENTER, 10 ) |
---|
228 | self.sizer_new_smear.Add( self.smear_description_pin_max,0, wx.CENTER, 10 ) |
---|
229 | self.sizer_new_smear.Add( self.smear_description_slit_width,0, wx.CENTER, 10 ) |
---|
230 | |
---|
231 | self.sizer_new_smear.Add( self.smear_pinhole_max,0, wx.CENTER, 10 ) |
---|
232 | self.sizer_new_smear.Add( self.smear_slit_width,0, wx.CENTER, 10 ) |
---|
233 | self.sizer_new_smear.Add( self.smear_data_right,0, wx.CENTER, 10 ) |
---|
234 | |
---|
235 | self.sizer_set_smearer.Add( self.smear_message_new_s,0, wx.CENTER, 10) |
---|
236 | self.sizer_set_smearer.Add( self.smear_message_new_p,0, wx.CENTER, 10) |
---|
237 | self.sizer_set_smearer.Add((5,2)) |
---|
238 | self.sizer_set_smearer.Add( self.sizer_new_smear,0, wx.CENTER, 10 ) |
---|
239 | |
---|
240 | # add all to chi2 sizer |
---|
241 | sizer_smearer_box.Add(self.sizer_set_smearer) |
---|
242 | |
---|
243 | sizer_chi2.Add(sizer_smearer_box) |
---|
244 | """ |
---|
245 | sizer_chi2.Add((-1,5)) |
---|
246 | """ |
---|
247 | # hide all smear messages and textctrl |
---|
248 | self._hide_all_smear_info() |
---|
249 | """ |
---|
250 | # get smear_selection |
---|
251 | self.current_smearer= smear_selection( self.data, self.model ) |
---|
252 | """ |
---|
253 | # Show only the relevant smear messages, etc |
---|
254 | if self.current_smearer == None: |
---|
255 | if not is_2Ddata: |
---|
256 | self.smear_description_none.Show(True) |
---|
257 | self.enable_smearer.Disable() |
---|
258 | else: |
---|
259 | self.smear_description_none.Show(True) |
---|
260 | #self.smear_description_2d.Show(True) |
---|
261 | #self.pinhole_smearer.Disable() |
---|
262 | self.slit_smearer.Disable() |
---|
263 | #self.enable_smearer.Disable() |
---|
264 | if self.data == None: |
---|
265 | self.slit_smearer.Disable() |
---|
266 | self.pinhole_smearer.Disable() |
---|
267 | self.enable_smearer.Disable() |
---|
268 | else: self._show_smear_sizer() |
---|
269 | """ |
---|
270 | boxsizer_range.Add(self.sizer_set_masking) |
---|
271 | #2D data? default |
---|
272 | is_2Ddata = False |
---|
273 | |
---|
274 | #check if it is 2D data |
---|
275 | if self.data.__class__.__name__ == "Data2D" or \ |
---|
276 | self.enable2D: |
---|
277 | is_2Ddata = True |
---|
278 | |
---|
279 | self.sizer5.Clear(True) |
---|
280 | |
---|
281 | self.qmin = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH,20), |
---|
282 | style=wx.TE_PROCESS_ENTER, |
---|
283 | text_enter_callback = self._onQrangeEnter) |
---|
284 | self.qmin.SetValue(str(self.qmin_x)) |
---|
285 | self.qmin.SetToolTipString("Minimun value of Q in linear scale.") |
---|
286 | |
---|
287 | self.qmax = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH,20), |
---|
288 | style=wx.TE_PROCESS_ENTER, |
---|
289 | text_enter_callback=self._onQrangeEnter) |
---|
290 | self.qmax.SetValue(str(self.qmax_x)) |
---|
291 | self.qmax.SetToolTipString("Maximum value of Q in linear scale.") |
---|
292 | |
---|
293 | id = wx.NewId() |
---|
294 | self.reset_qrange =wx.Button(self,id,'Reset',size=(77,20)) |
---|
295 | |
---|
296 | self.reset_qrange.Bind(wx.EVT_BUTTON, self.on_reset_clicked,id=id) |
---|
297 | self.reset_qrange.SetToolTipString("Reset Q range to the default values") |
---|
298 | |
---|
299 | sizer_horizontal=wx.BoxSizer(wx.HORIZONTAL) |
---|
300 | sizer= wx.GridSizer(2, 4, 2, 6) |
---|
301 | |
---|
302 | self.btEditMask = wx.Button(self,wx.NewId(),'Editor', size=(88,23)) |
---|
303 | self.btEditMask.Bind(wx.EVT_BUTTON, self._onMask,id= self.btEditMask.GetId()) |
---|
304 | self.btEditMask.SetToolTipString("Edit Mask.") |
---|
305 | self.EditMask_title = wx.StaticText(self, -1, ' Masking(2D)') |
---|
306 | |
---|
307 | sizer.Add(wx.StaticText(self, -1, 'Q range')) |
---|
308 | sizer.Add(wx.StaticText(self, -1, ' Min[1/A]')) |
---|
309 | sizer.Add(wx.StaticText(self, -1, ' Max[1/A]')) |
---|
310 | sizer.Add(self.EditMask_title) |
---|
311 | #sizer.Add(wx.StaticText(self, -1, '')) |
---|
312 | sizer.Add(self.reset_qrange) |
---|
313 | sizer.Add(self.qmin) |
---|
314 | sizer.Add(self.qmax) |
---|
315 | #sizer.Add(self.theory_npts_tcrtl) |
---|
316 | sizer.Add(self.btEditMask) |
---|
317 | boxsizer_range.Add(sizer_chi2) |
---|
318 | boxsizer_range.Add((10,10)) |
---|
319 | boxsizer_range.Add(sizer) |
---|
320 | |
---|
321 | boxsizer_range.Add((10,15)) |
---|
322 | boxsizer_range.Add(sizer_fit) |
---|
323 | if is_2Ddata: |
---|
324 | self.btEditMask.Enable() |
---|
325 | self.EditMask_title.Enable() |
---|
326 | else: |
---|
327 | self.btEditMask.Disable() |
---|
328 | self.EditMask_title.Disable() |
---|
329 | """ |
---|
330 | ## save state |
---|
331 | self.save_current_state() |
---|
332 | """ |
---|
333 | self.sizer5.Add(boxsizer_range,0, wx.EXPAND | wx.ALL, 10) |
---|
334 | self.sizer5.Layout() |
---|
335 | |
---|
336 | def _on_select_model(self, event=None): |
---|
337 | """ |
---|
338 | call back for model selection |
---|
339 | """ |
---|
340 | |
---|
341 | self.Show(False) |
---|
342 | self._on_select_model_helper() |
---|
343 | self.set_model_param_sizer(self.model) |
---|
344 | if self.model is None: |
---|
345 | self._set_bookmark_flag(False) |
---|
346 | self._keep.Enable(False) |
---|
347 | self._set_save_flag(False) |
---|
348 | self.enable_disp.SetValue(False) |
---|
349 | self.disable_disp.SetValue(True) |
---|
350 | try: |
---|
351 | self.set_dispers_sizer() |
---|
352 | except: |
---|
353 | pass |
---|
354 | """ |
---|
355 | #self.btFit.SetFocus() |
---|
356 | self.state.enable_disp = self.enable_disp.GetValue() |
---|
357 | self.state.disable_disp = self.disable_disp.GetValue() |
---|
358 | self.state.pinhole_smearer = self.pinhole_smearer.GetValue() |
---|
359 | self.state.slit_smearer = self.slit_smearer.GetValue() |
---|
360 | """ |
---|
361 | self.state.structurecombobox = self.structurebox.GetCurrentSelection() |
---|
362 | self.state.formfactorcombobox = self.formfactorbox.GetCurrentSelection() |
---|
363 | |
---|
364 | if self.model != None: |
---|
365 | self._set_copy_flag(True) |
---|
366 | self._set_paste_flag(True) |
---|
367 | if self.data != None: |
---|
368 | self._set_bookmark_flag(False) |
---|
369 | self._keep.Enable(False) |
---|
370 | |
---|
371 | temp_smear = None |
---|
372 | """ |
---|
373 | #self._set_save_flag(True) |
---|
374 | # Reset smearer, model and data |
---|
375 | self._set_smear(self.data) |
---|
376 | try: |
---|
377 | # update smearer sizer |
---|
378 | self.onSmear(None) |
---|
379 | temp_smear = None |
---|
380 | if self.enable_smearer.GetValue(): |
---|
381 | # Set the smearer environments |
---|
382 | temp_smear = self.smearer |
---|
383 | except: |
---|
384 | raise |
---|
385 | ## error occured on chisqr computation |
---|
386 | #pass |
---|
387 | """ |
---|
388 | ## event to post model to fit to fitting plugins |
---|
389 | (ModelEventbox, EVT_MODEL_BOX) = wx.lib.newevent.NewEvent() |
---|
390 | |
---|
391 | ## set smearing value whether or not |
---|
392 | # the data contain the smearing info |
---|
393 | evt = ModelEventbox(model=self.model, |
---|
394 | smearer=temp_smear, |
---|
395 | qmin=float(self.qmin_x), |
---|
396 | uid=self.uid, |
---|
397 | qmax=float(self.qmax_x)) |
---|
398 | |
---|
399 | self._manager._on_model_panel(evt=evt) |
---|
400 | self.mbox_description.SetLabel("Model [%s]" % str(self.model.name)) |
---|
401 | self.state.model = self.model.clone() |
---|
402 | self.state.model.name = self.model.name |
---|
403 | |
---|
404 | |
---|
405 | if event != None: |
---|
406 | ## post state to fit panel |
---|
407 | new_event = PageInfoEvent(page = self) |
---|
408 | wx.PostEvent(self.parent, new_event) |
---|
409 | #update list of plugins if new plugin is available |
---|
410 | if self.plugin_rbutton.GetValue(): |
---|
411 | temp = self.parent.update_model_list() |
---|
412 | if temp: |
---|
413 | self.model_list_box = temp |
---|
414 | current_val = self.formfactorbox.GetValue() |
---|
415 | pos = self.formfactorbox.GetSelection() |
---|
416 | self._show_combox_helper() |
---|
417 | self.formfactorbox.SetSelection(pos) |
---|
418 | self.formfactorbox.SetValue(current_val) |
---|
419 | self._onDraw(event=None) |
---|
420 | else: |
---|
421 | self._draw_model() |
---|
422 | self.SetupScrolling() |
---|
423 | self.Show(True) |
---|
424 | |
---|
425 | def _update_paramv_on_fit(self): |
---|
426 | """ |
---|
427 | make sure that update param values just before the fitting |
---|
428 | """ |
---|
429 | #flag for qmin qmax check values |
---|
430 | flag = True |
---|
431 | self.fitrange = True |
---|
432 | is_modified = False |
---|
433 | |
---|
434 | #wx.PostEvent(self._manager.parent, StatusEvent(status=" \ |
---|
435 | #updating ... ",type="update")) |
---|
436 | |
---|
437 | ##So make sure that update param values on_Fit. |
---|
438 | #self._undo.Enable(True) |
---|
439 | if self.model !=None: |
---|
440 | ##Check the values |
---|
441 | self._check_value_enter( self.fittable_param ,is_modified) |
---|
442 | self._check_value_enter( self.fixed_param ,is_modified) |
---|
443 | self._check_value_enter( self.parameters ,is_modified) |
---|
444 | |
---|
445 | # If qmin and qmax have been modified, update qmin and qmax and |
---|
446 | # Here we should check whether the boundaries have been modified. |
---|
447 | # If qmin and qmax have been modified, update qmin and qmax and |
---|
448 | # set the is_modified flag to True |
---|
449 | self.fitrange = self._validate_qrange(self.qmin, self.qmax) |
---|
450 | if self.fitrange: |
---|
451 | tempmin = float(self.qmin.GetValue()) |
---|
452 | if tempmin != self.qmin_x: |
---|
453 | self.qmin_x = tempmin |
---|
454 | tempmax = float(self.qmax.GetValue()) |
---|
455 | if tempmax != self.qmax_x: |
---|
456 | self.qmax_x = tempmax |
---|
457 | if tempmax == tempmin: |
---|
458 | flag = False |
---|
459 | temp_smearer = None |
---|
460 | """ |
---|
461 | if not self.disable_smearer.GetValue(): |
---|
462 | temp_smearer= self.current_smearer |
---|
463 | if self.slit_smearer.GetValue(): |
---|
464 | flag = self.update_slit_smear() |
---|
465 | elif self.pinhole_smearer.GetValue(): |
---|
466 | flag = self.update_pinhole_smear() |
---|
467 | else: |
---|
468 | self._manager.set_smearer(smearer=temp_smearer, |
---|
469 | uid=self.uid, |
---|
470 | qmin=float(self.qmin_x), |
---|
471 | qmax=float(self.qmax_x), |
---|
472 | draw=False) |
---|
473 | elif not self._is_2D(): |
---|
474 | self._manager.set_smearer(smearer=temp_smearer, |
---|
475 | qmin=float(self.qmin_x), |
---|
476 | uid=self.uid, |
---|
477 | qmax= float(self.qmax_x), |
---|
478 | draw=False) |
---|
479 | |
---|
480 | if self.data != None: |
---|
481 | index_data = ((self.qmin_x <= self.data.x)&\ |
---|
482 | (self.data.x <= self.qmax_x)) |
---|
483 | val = str(len(self.data.x[index_data==True])) |
---|
484 | self.Npts_fit.SetValue(val) |
---|
485 | else: |
---|
486 | # No data in the panel |
---|
487 | try: |
---|
488 | self.npts_x = float(self.Npts_total.GetValue()) |
---|
489 | except: |
---|
490 | flag = False |
---|
491 | return flag |
---|
492 | flag = True |
---|
493 | """ |
---|
494 | if self._is_2D(): |
---|
495 | # only 2D case set mask |
---|
496 | flag = self._validate_Npts() |
---|
497 | if not flag: |
---|
498 | return flag |
---|
499 | else: flag = False |
---|
500 | else: |
---|
501 | flag = False |
---|
502 | |
---|
503 | #For invalid q range, disable the mask editor and fit button, vs. |
---|
504 | if not self.fitrange: |
---|
505 | #self.btFit.Disable() |
---|
506 | if self._is_2D(): |
---|
507 | self.btEditMask.Disable() |
---|
508 | else: |
---|
509 | #self.btFit.Enable(True) |
---|
510 | if self._is_2D() and self.data != None: |
---|
511 | self.btEditMask.Enable(True) |
---|
512 | |
---|
513 | if not flag: |
---|
514 | msg = "Cannot Plot or Fit :Must select a " |
---|
515 | msg += " model or Fitting range is not valid!!! " |
---|
516 | wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) |
---|
517 | |
---|
518 | self.save_current_state() |
---|
519 | |
---|
520 | return flag |
---|
521 | def save_current_state(self): |
---|
522 | """ |
---|
523 | Currently no save option implemented for batch page |
---|
524 | """ |
---|
525 | pass |
---|
526 | def save_current_state_fit(self): |
---|
527 | """ |
---|
528 | Currently no save option implemented for batch page |
---|
529 | """ |
---|
530 | pass |
---|
531 | def set_data(self, data): |
---|
532 | """ |
---|
533 | reset the current data |
---|
534 | """ |
---|
535 | id = None |
---|
536 | group_id = None |
---|
537 | flag = False |
---|
538 | if self.data is None and data is not None: |
---|
539 | flag = True |
---|
540 | if data is not None: |
---|
541 | id = data.id |
---|
542 | group_id = data.group_id |
---|
543 | if self.data is not None: |
---|
544 | flag = (data.id != self.data.id) |
---|
545 | self.data = data |
---|
546 | if self.data is None: |
---|
547 | data_min = "" |
---|
548 | data_max = "" |
---|
549 | data_name = "" |
---|
550 | self._set_bookmark_flag(False) |
---|
551 | self._keep.Enable(False) |
---|
552 | self._set_save_flag(False) |
---|
553 | else: |
---|
554 | if self.model != None: |
---|
555 | self._set_bookmark_flag(False) |
---|
556 | self._keep.Enable(False) |
---|
557 | self._set_save_flag(False) |
---|
558 | self._set_preview_flag(True) |
---|
559 | """ |
---|
560 | self._set_smear(data) |
---|
561 | # more disables for 2D |
---|
562 | if self.data.__class__.__name__ == "Data2D" or \ |
---|
563 | self.enable2D: |
---|
564 | self.slit_smearer.Disable() |
---|
565 | self.pinhole_smearer.Enable(True) |
---|
566 | self.default_mask = copy.deepcopy(self.data.mask) |
---|
567 | else: |
---|
568 | self.slit_smearer.Enable(True) |
---|
569 | self.pinhole_smearer.Enable(True) |
---|
570 | """ |
---|
571 | self.formfactorbox.Enable() |
---|
572 | self.structurebox.Enable() |
---|
573 | data_name = self.data.name |
---|
574 | #set maximum range for x in linear scale |
---|
575 | if not hasattr(self.data,"data"): #Display only for 1D data fit |
---|
576 | # Minimum value of data |
---|
577 | data_min = min(self.data.x) |
---|
578 | # Maximum value of data |
---|
579 | data_max = max(self.data.x) |
---|
580 | """ |
---|
581 | #number of total data points |
---|
582 | self.Npts_total.SetValue(str(len(self.data.x))) |
---|
583 | #default:number of data points selected to fit |
---|
584 | self.Npts_fit.SetValue(str(len(self.data.x))) |
---|
585 | """ |
---|
586 | self.btEditMask.Disable() |
---|
587 | self.EditMask_title.Disable() |
---|
588 | else: |
---|
589 | |
---|
590 | ## Minimum value of data |
---|
591 | data_min = 0 |
---|
592 | x = max(math.fabs(self.data.xmin), math.fabs(self.data.xmax)) |
---|
593 | y = max(math.fabs(self.data.ymin), math.fabs(self.data.ymax)) |
---|
594 | ## Maximum value of data |
---|
595 | data_max = math.sqrt(x*x + y*y) |
---|
596 | """ |
---|
597 | #number of total data points |
---|
598 | self.Npts_total.SetValue(str(len(self.data.data))) |
---|
599 | #default:number of data points selected to fit |
---|
600 | self.Npts_fit.SetValue(str(len(self.data.data))) |
---|
601 | """ |
---|
602 | self.btEditMask.Enable() |
---|
603 | self.EditMask_title.Enable() |
---|
604 | """ |
---|
605 | self.Npts_total.SetEditable(False) |
---|
606 | self.Npts_total.SetBackgroundColour(\ |
---|
607 | self.GetParent().GetBackgroundColour()) |
---|
608 | |
---|
609 | self.Npts_total.Bind(wx.EVT_MOUSE_EVENTS, self._npts_click) |
---|
610 | #self.Npts_total.Disable() |
---|
611 | """ |
---|
612 | self.dataSource.SetValue(data_name) |
---|
613 | self.qmin_x = data_min |
---|
614 | self.qmax_x = data_max |
---|
615 | #self.minimum_q.SetValue(str(data_min)) |
---|
616 | #self.maximum_q.SetValue(str(data_max)) |
---|
617 | self.qmin.SetValue(str(data_min)) |
---|
618 | self.qmax.SetValue(str(data_max)) |
---|
619 | self.qmin.SetBackgroundColour("white") |
---|
620 | self.qmax.SetBackgroundColour("white") |
---|
621 | self.state.data = data |
---|
622 | self.state.qmin = self.qmin_x |
---|
623 | self.state.qmax = self.qmax_x |
---|
624 | |
---|
625 | #update model plot with new data information |
---|
626 | if flag: |
---|
627 | #set model view button |
---|
628 | if self.data.__class__.__name__ == "Data2D": |
---|
629 | self.enable2D = True |
---|
630 | self.model_view.SetLabel("2D Mode") |
---|
631 | else: |
---|
632 | self.enable2D = False |
---|
633 | self.model_view.SetLabel("1D Mode") |
---|
634 | |
---|
635 | self.model_view.Disable() |
---|
636 | |
---|
637 | #replace data plot on combo box selection |
---|
638 | #by removing the previous selected data |
---|
639 | #wx.PostEvent(self._manager.parent, NewPlotEvent(action="remove", |
---|
640 | # group_id=group_id, id=id)) |
---|
641 | wx.PostEvent(self._manager.parent, |
---|
642 | NewPlotEvent(group_id=group_id, |
---|
643 | action="delete")) |
---|
644 | #plot the current selected data |
---|
645 | wx.PostEvent(self._manager.parent, NewPlotEvent(plot=self.data, |
---|
646 | title=str(self.data.title))) |
---|
647 | self._manager.store_data(uid=self.uid, data=data, |
---|
648 | data_list=self.data_list, |
---|
649 | caption=self.window_name) |
---|
650 | self._draw_model() |
---|
651 | |
---|
652 | |
---|
653 | |
---|
654 | class BGTextCtrl(wx.TextCtrl): |
---|
655 | """ |
---|
656 | Text control used to display outputs. |
---|
657 | No editing allowed. The background is |
---|
658 | grayed out. User can't select text. |
---|
659 | """ |
---|
660 | def __init__(self, *args, **kwds): |
---|
661 | wx.TextCtrl.__init__(self, *args, **kwds) |
---|
662 | self.SetEditable(False) |
---|
663 | self.SetBackgroundColour(self.GetParent().parent.GetBackgroundColour()) |
---|
664 | |
---|
665 | # Bind to mouse event to avoid text highlighting |
---|
666 | # The event will be skipped once the call-back |
---|
667 | # is called. |
---|
668 | self.Bind(wx.EVT_MOUSE_EVENTS, self._click) |
---|
669 | |
---|
670 | def _click(self, event): |
---|
671 | """ |
---|
672 | Prevent further handling of the mouse event |
---|
673 | by not calling Skip(). |
---|
674 | """ |
---|
675 | pass |
---|
676 | |
---|