source: sasview/sansview/perspectives/fitting/fitpage.py @ 6d91073

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 6d91073 was 6d91073, checked in by Jae Cho <jhjcho@…>, 15 years ago

fixed dipspersion errors displaying wrong values

  • Property mode set to 100644
File size: 65.3 KB
Line 
1
2
3import sys
4import wx
5import wx.lib.newevent
6import numpy
7import copy
8import math
9from sans.models.dispersion_models import ArrayDispersion, GaussianDispersion
10
11from sans.guicomm.events import StatusEvent   
12from sans.guiframe.utils import format_number,check_float
13
14## event to post model to fit to fitting plugins
15(ModelEventbox, EVT_MODEL_BOX) = wx.lib.newevent.NewEvent()
16
17## event to know the selected fit engine
18(FitterTypeEvent, EVT_FITTER_TYPE)   = wx.lib.newevent.NewEvent()
19(FitStopEvent, EVT_FIT_STOP)   = wx.lib.newevent.NewEvent()
20_BOX_WIDTH = 76
21
22import basepage
23from basepage import BasicPage
24from basepage import PageInfoEvent
25from DataLoader.qsmearing import smear_selection
26
27class FitPage(BasicPage):
28    """
29        FitPanel class contains fields allowing to display results when
30        fitting  a model and one data
31        @note: For Fit to be performed the user should check at least one parameter
32        on fit Panel window.
33 
34    """
35    def __init__(self,parent, page_info):
36        BasicPage.__init__(self, parent, page_info)
37        """
38            Initialization of the Panel
39        """
40        ## fit page does not content npts txtcrtl
41        self.npts=None
42        ## thread for compute Chisqr
43        self.calc_Chisqr=None
44        ## default fitengine type
45        self.engine_type = None
46        ## draw sizer
47        self._fill_datainfo_sizer()
48       
49        self._fill_model_sizer( self.sizer1)
50 
51        self._fill_range_sizer() 
52        #self._on_select_model(event=None)
53        if self.data !=None:
54            self.smearer = smear_selection( self.data )
55            if self.smearer ==None:
56                self.enable_smearer.Disable()
57                self.disable_smearer.Disable()
58       
59        ## to update the panel according to the fit engine type selected
60        self.Bind(EVT_FITTER_TYPE,self._on_engine_change)
61        self.Bind(EVT_FIT_STOP,self._on_fit_complete)
62   
63    def _on_fit_complete(self, event):
64        """
65            When fit is complete ,reset the fit button label.
66        """
67        #self.btFit.SetLabel("Fit")
68        #self.btFit.Unbind(event=wx.EVT_BUTTON, id=self.btFit.GetId())
69        #self.btFit.Bind(event=wx.EVT_BUTTON, handler=self._onFit,id=self.btFit.GetId())
70        pass
71       
72       
73    def _on_engine_change(self, event):
74        """
75            get an event containing the current name of the fit engine type
76            @param event: FitterTypeEvent containing  the name of the current engine
77        """
78        self.engine_type = event.type
79         
80        if len(self.parameters)==0:
81            return
82        if event.type =="park":
83            self.btFit.SetLabel("Fit")
84
85        for item in self.parameters:
86            if event.type =="scipy" :
87                item[5].SetValue("")
88                item[5].Hide()
89                item[6].SetValue("")
90                item[6].Hide()
91                self.text2_min.Hide()
92                self.text2_max.Hide()
93            else:
94                item[5].Show(True)
95                item[6].Show(True)
96                self.text2_min.Show(True)
97                self.text2_max.Show(True)
98        for item in self.fittable_param:
99            if item[5]!=None and item[6]!=None and not item in self.orientation_params_disp:
100                if event.type =="scipy" and not item in self.orientation_params:
101                    item[5].SetValue("")
102                    item[5].Hide()
103                    item[6].SetValue("")
104                    item[6].Hide()
105                    self.text2_min.Hide()
106                    self.text2_max.Hide()
107                    self.text_disp_min.Hide()
108                    self.text_disp_max.Hide()
109                else:
110                    item[5].Show(True)
111                    item[6].Show(True)
112                    self.text2_min.Show(True)
113                    self.text2_max.Show(True)
114                    self.text_disp_min.Show(True)
115                    self.text_disp_max.Show(True)
116           
117        for item in self.orientation_params:
118            if item[5]!=None and item[6]!=None:
119                if event.type =="scipy" or self.data.__class__.__name__ !="Data2D":
120                    item[5].SetValue("")
121                    item[5].Hide()
122                    item[6].SetValue("")
123                    item[6].Hide()
124                else:
125                    item[5].Show(True)
126                    item[6].Show(True)
127                   
128        for item in self.orientation_params_disp:         
129            if item[5]!=None and item[6]!=None:
130                if event.type =="scipy" or self.data.__class__.__name__ !="Data2D":
131                    item[5].SetValue("")
132                    item[5].Hide()
133                    item[6].SetValue("")
134                    item[6].Hide()
135                else:
136                    item[5].Show(True)
137                    item[6].Show(True)
138        self.Layout()
139
140       
141   
142    def _fill_range_sizer(self):
143        """
144            Fill the sizer containing the plotting range
145            add  access to npts
146        """
147        title = "Fitting"
148        box_description_range = wx.StaticBox(self, -1,str(title))
149        boxsizer_range = wx.StaticBoxSizer(box_description_range, wx.VERTICAL)
150
151        sizer_fit = wx.GridSizer(1, 1,0, 0)
152   
153        self.btFit = wx.Button(self,wx.NewId(),'Fit', size=(80,23))
154        self.btFit.Bind(wx.EVT_BUTTON, self._onFit,id= self.btFit.GetId())
155        self.btFit.SetToolTipString("Perform fit.")
156     
157       
158        sizer_fit.Add((5,5),1, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)       
159        sizer_fit.Add(self.btFit,0, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 35) 
160        sizer_fit.Layout()
161        sizer_smearer = wx.BoxSizer(wx.HORIZONTAL)
162        #Filling the sizer containing instruments smearing info.
163        self.disable_smearer = wx.RadioButton(self, -1, 'No', style=wx.RB_GROUP)
164        self.enable_smearer = wx.RadioButton(self, -1, 'Yes')
165        self.Bind(wx.EVT_RADIOBUTTON, self.onSmear, id=self.disable_smearer.GetId())
166        self.Bind(wx.EVT_RADIOBUTTON, self.onSmear, id=self.enable_smearer.GetId())
167        self.disable_smearer.SetValue(True)
168       
169        sizer_smearer.Add(wx.StaticText(self,-1,'Instrument Smearing? '))
170        sizer_smearer.Add((10, 10))
171        sizer_smearer.Add( self.enable_smearer )
172        sizer_smearer.Add((10,10))
173        sizer_smearer.Add( self.disable_smearer )
174        #Display Chi^2/dof
175        sizer_smearer.Add((78,10))
176        box_description= wx.StaticBox(self, -1,'Chi2/dof')
177        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
178        boxsizer1.SetMinSize((80,-1))
179        temp_smearer = None
180        if self.enable_smearer.GetValue():
181            temp_smearer= self.smearer
182       
183        self.tcChi    =  wx.StaticText(self, -1, "-", style=wx.ALIGN_LEFT)
184         
185        boxsizer1.Add( self.tcChi )   
186        sizer_smearer.Add( boxsizer1 )
187               
188        #Set sizer for Fitting section
189        self._set_range_sizer( title=title,box_sizer=boxsizer_range, object1=sizer_smearer, object= sizer_fit)
190 
191       
192    def _fill_datainfo_sizer(self):
193        """
194            fill sizer 0 with data info
195        """
196        self.sizer0.Clear(True)
197        ## no loaded data , don't fill the sizer
198        if self.data== None:
199            self.sizer0.Layout()
200            return
201       
202        box_description= wx.StaticBox(self, -1, 'Data')
203        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
204        #----------------------------------------------------------
205        sizer_data = wx.GridSizer(3, 3,5, 5)
206        #Filling the sizer containing data related fields
207        DataSource  =wx.StaticText(self, -1,str(self.data.name))
208
209        sizer_data.Add(wx.StaticText(self, -1, 'Source Name : '))
210        sizer_data.Add(DataSource )
211        sizer_data.Add( (0,5) )
212       
213        #---------sizer 2 draw--------------------------------
214        #set maximum range for x in linear scale
215        if not hasattr(self.data,"data"): #Display only for 1D data fit
216            # Minimum value of data   
217            data_min = min(self.data.x)
218            # Maximum value of data 
219            data_max = max(self.data.x)
220            text4_3 = wx.StaticText(self, -1, 'Total Q Range (1/A)',
221                                     style=wx.ALIGN_LEFT)
222            sizer_data.Add( text4_3 )
223            sizer_data.Add(wx.StaticText(self, -1, "Min : %s"%str(data_min)))
224            sizer_data.Add(wx.StaticText(self, -1, "Max : %s"%str(data_max)))
225           
226        else:
227            ## Minimum value of data
228            data_min= 0
229            x= max(math.fabs(self.data.xmin), math.fabs(self.data.xmax)) 
230            y= max(math.fabs(self.data.ymin), math.fabs(self.data.ymax))
231            ## Maximum value of data 
232            data_max = math.sqrt(x*x + y*y)
233         
234            #For qmin and qmax, do not use format_number
235            #.(If do, qmin and max could be different from what is in the data.)
236            text4_3 = wx.StaticText(self, -1, "Total Q Range (1/A)",
237                                     style=wx.ALIGN_LEFT)
238            sizer_data.Add( text4_3 )
239            sizer_data.Add(wx.StaticText(self, -1, "Min : %s"%str(data_min)))
240            sizer_data.Add(wx.StaticText(self, -1, "Max : %s"%str(data_max)))
241        ## set q range to plot
242        self.qmin_x= data_min
243        self.qmax_x= data_max
244
245        boxsizer1.Add(sizer_data)
246        #------------------------------------------------------------
247        self.sizer0.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10)
248        self.sizer0.Layout()
249       
250    def _fill_model_sizer(self, sizer):
251        """
252            fill sizer containing model info
253        """
254        ##Add model function Details button in fitpanel.
255        ##The following 3 lines are for Mac. Let JHC know before modifying...
256        title = "Model"
257        box_description= wx.StaticBox(self, -1,str(title))
258        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
259         
260        id = wx.NewId()
261        self.model_help =wx.Button(self,id,'Details', size=(80,23))
262        self.model_help.Bind(wx.EVT_BUTTON, self.on_model_help_clicked,id=id)
263        self.model_help.SetToolTipString("Model Function Help")
264       
265        ## class base method  to add view 2d button   
266        self._set_model_sizer(sizer=sizer, box_sizer=boxsizer1, title="Model",object=self.model_help )   
267
268   
269    #def _set_sizer_gaussian(self):
270    def _set_sizer_dispersion(self, dispersity):
271        """
272            draw sizer with gaussian dispersity parameters
273        """
274        self.fittable_param=[]
275        self.fixed_param=[]
276        self.orientation_params_disp=[]
277
278        self.sizer4_4.Clear(True)
279        if self.model==None:
280            ##no model is selected
281            return
282        if not self.enable_disp.GetValue():
283            ## the user didn't select dispersity display
284            return 
285
286        self._reset_dispersity()
287        # Create the dispersion objects
288        for item in self.model.dispersion.keys():
289            #disp_model =  GaussianDispersion()
290            disp_model = dispersity()
291            self._disp_obj_dict[item] = disp_model
292            self.model.set_dispersion(item, disp_model)
293            self.state._disp_obj_dict[item]= disp_model
294
295        ix=0
296        iy=1
297        disp = wx.StaticText(self, -1, 'Names')
298        self.sizer4_4.Add(disp,( iy, ix),(1,1), 
299                           wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
300        ix += 1 
301        values = wx.StaticText(self, -1, 'Sigmas (STD)')
302        self.sizer4_4.Add(values,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
303        ix +=2 
304        self.text_disp_1 = wx.StaticText(self, -1, '')
305        self.sizer4_4.Add( self.text_disp_1,(iy, ix),(1,1),\
306                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
307        self.text_disp_1.Hide()
308       
309       
310        ix +=1 
311        self.text_disp_min = wx.StaticText(self, -1, 'Min')
312        self.sizer4_4.Add(self.text_disp_min,(iy, ix),(1,1),\
313                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
314        self.text_disp_min.Hide()
315        ix +=1 
316        self.text_disp_max = wx.StaticText(self, -1, 'Max')
317        self.sizer4_4.Add(self.text_disp_max,(iy, ix),(1,1),\
318                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
319        self.text_disp_max.Hide()
320                       
321       
322       
323       
324       
325       
326        ix += 1 
327        npts = wx.StaticText(self, -1, 'Npts')
328        self.sizer4_4.Add(npts,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
329        ix += 1 
330        nsigmas = wx.StaticText(self, -1, 'Nsigmas')
331        self.sizer4_4.Add(nsigmas,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
332       
333        if self.engine_type=="park":
334            self.text_disp_max.Show(True)
335            self.text_disp_min.Show(True)
336
337        for item in self.model.dispersion.keys():
338            if not item in self.model.orientation_params:
339                self.disp_cb_dict[item]= None
340                name1=item+".width"
341                name2=item+".npts"
342                name3=item+".nsigmas"
343                if not self.model.details.has_key(name1):
344                    self.model.details [name1] = ["",None, None, None]                           
345
346                iy += 1
347                for p in self.model.dispersion[item].keys(): 
348       
349                    if p=="width":
350                        ix = 0
351                        cb = wx.CheckBox(self, -1, name1, (10, 10))
352                        wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param)
353                        self.sizer4_4.Add( cb,( iy, ix),(1,1), 
354                                           wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
355                        ix = 1
356                        value= self.model.getParam(name1)
357                        ctl1 = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH,20),
358                                            style=wx.TE_PROCESS_ENTER)
359                        ctl1.SetValue(str (format_number(value)))
360                        self.sizer4_4.Add(ctl1, (iy,ix),(1,1),wx.EXPAND)
361                        ## text to show error sign
362                        ix = 2
363                        text2=wx.StaticText(self, -1, '+/-')
364                        self.sizer4_4.Add(text2,(iy, ix),(1,1),
365                                          wx.EXPAND|wx.ADJUST_MINSIZE, 0)
366                        text2.Hide() 
367                        ## txtcrtl to add error from fit
368                        fit_errs = self.model.details[item][3]
369                     
370                        ix = 3
371                        ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER)
372                        ctl2.SetValue(str(format_number(fit_errs)))
373                        self.sizer4_4.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
374                        if fit_errs==None or not numpy.isfinite(fit_errs):
375                            ctl2.Hide()
376                        else:
377                            if not text2.IsShown():
378                                text2.Show(True)
379                            ctl2.Show(True)
380                        #Prepare add min and max in model.details.(Maybe Not correct way)
381                        param_min, param_max= self.model.details[name1][1:3]
382                        ix = 4
383                        ctl3 = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
384                                                       kill_focus_callback = self._on_paramRangeEnter,
385                                                       set_focus_callback  = self._on_paramRangeEnter)
386                        if param_min ==None or not numpy.isfinite(param_min):
387                            ctl3.SetValue("")
388                        else:
389                            ctl3.SetValue(str(param_min))
390                        self.sizer4_4.Add(ctl3, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
391                        ctl3.Hide()
392               
393                        ix = 5
394                        ctl4 = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
395                                                       kill_focus_callback = self._on_paramRangeEnter,
396                                                       set_focus_callback  = self._on_paramRangeEnter)
397                        self.sizer4_4.Add(ctl4, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
398                        if param_max==None or not numpy.isfinite(param_max):
399                            ctl4.SetValue("")
400                        else:
401                            ctl4.SetValue(str(param_max))
402                        ctl4.Hide()
403                       
404                        if self.engine_type=="park":
405                            ctl3.Show(True)
406                            ctl4.Show(True)
407                                         
408                        self.fittable_param.append([cb,name1,ctl1,text2,
409                                                    ctl2, ctl3, ctl4,None])                   
410                   
411                    elif p=="npts":
412                            ix = 6
413                            value= self.model.getParam(name2)
414                            Tctl = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20),
415                                                style=wx.TE_PROCESS_ENTER)
416                           
417                            Tctl.SetValue(str (format_number(value)))
418                            self.sizer4_4.Add(Tctl, (iy,ix),(1,1),
419                                               wx.EXPAND|wx.ADJUST_MINSIZE, 0)
420                            self.fixed_param.append([None,name2, Tctl,None,None,
421                                                      None, None,None])
422                    elif p=="nsigmas":
423                            ix = 7
424                            value= self.model.getParam(name3)
425                            Tctl = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20),
426                                                style=wx.TE_PROCESS_ENTER)
427                            Tctl.SetValue(str (format_number(value)))
428                            self.sizer4_4.Add(Tctl, (iy,ix),(1,1),
429                                               wx.EXPAND|wx.ADJUST_MINSIZE, 0)
430                            ix +=1
431                            self.sizer4_4.Add((20,20), (iy,ix),(1,1),
432                                               wx.EXPAND|wx.ADJUST_MINSIZE, 0)
433                           
434                            self.fixed_param.append([None,name3, Tctl
435                                                     ,None,None,None, None,None])
436                           
437        ix =0
438        iy +=1 
439        self.sizer4_4.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 
440        for item in self.model.dispersion.keys():
441            if  item in self.model.orientation_params:
442                self.disp_cb_dict[item]= None
443                name1=item+".width"
444                name2=item+".npts"
445                name3=item+".nsigmas"
446                if not self.model.details.has_key(name1):
447                    self.model.details [name1] = ["",None, None, None]                 
448                iy += 1
449                for p in self.model.dispersion[item].keys(): 
450       
451                    if p=="width":
452                        ix = 0
453                        cb = wx.CheckBox(self, -1, name1, (10, 10))
454                        wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param)
455                        self.sizer4_4.Add( cb,( iy, ix),(1,1), 
456                                           wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
457                        if self.data.__class__.__name__ =="Data2D":
458                            cb.Show(True)
459                        elif cb.IsShown():
460                            cb.Hide()
461                        ix = 1
462                        value= self.model.getParam(name1)
463                        ctl1 = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH,20),
464                                            style=wx.TE_PROCESS_ENTER)
465                        ctl1.SetValue(str (format_number(value)))
466                        if self.data.__class__.__name__ =="Data2D":
467                            ctl1.Show(True)
468                        elif ctl1.IsShown():
469                            ctl1.Hide()
470                        self.sizer4_4.Add(ctl1, (iy,ix),(1,1),wx.EXPAND)
471                        ## text to show error sign
472                        ix = 2
473                        text2=wx.StaticText(self, -1, '+/-')
474                        self.sizer4_4.Add(text2,(iy, ix),(1,1),
475                                          wx.EXPAND|wx.ADJUST_MINSIZE, 0)
476                        text2.Hide() 
477                        ## txtcrtl to add error from fit                       
478                        fit_errs = self.model.details[item][3]                   
479                        ix = 3
480                        ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER)
481                        ctl2.SetValue(str(format_number(fit_errs)))
482                        self.sizer4_4.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
483                        if fit_errs==None or not numpy.isfinite(fit_errs) or self.data.__class__.__name__ !="Data2D":
484                            ctl2.Hide()
485                        else:
486                            if not text2.IsShown():
487                                text2.Show(True)
488                            ctl2.Show(True)
489                        #if self.data.__class__.__name__ =="Data2D":
490                            #ctl2.Show(True)
491                        #elif ctl2.IsShown():
492                            #ctl2.Hide()
493                           
494                        param_min, param_max= self.model.details[name1][1:3]
495                        ix = 4
496                        ctl3 = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
497                                                       kill_focus_callback = self._onparamRangeEnter,
498                                                       set_focus_callback  = self._onparamRangeEnter)
499                        if param_min ==None or not numpy.isfinite(param_min):
500                            ctl3.SetValue("")
501                        else:
502                            ctl3.SetValue(str(param_min))
503                        self.sizer4_4.Add(ctl3, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
504
505                        ctl3.Hide()
506               
507                        ix = 5
508                        ctl4 = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
509                                                       kill_focus_callback = self._onparamRangeEnter,
510                                                       set_focus_callback  = self._onparamRangeEnter)
511                        self.sizer4_4.Add(ctl4, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
512                        if param_max==None or not numpy.isfinite(param_max):
513                            ctl4.SetValue("")
514                        else:
515                            ctl4.SetValue(str(param_max))
516                        ctl4.Hide()
517                        #if self.data.__class__.__name__ =="Data2D":
518                            #ctl4.Enable(True)
519                        #elif ctl4.Shown():
520                            #ctl4.Hide()
521                       
522                        if self.engine_type=="park" and self.data.__class__.__name__ =="Data2D":
523                            ctl3.Show(True)
524                            ctl3.Enable(True)
525                            ctl4.Show(True) 
526                            ctl4.Enable(True)                           
527                           
528                           
529                           
530                           
531                        self.fittable_param.append([cb,name1,ctl1,text2,
532                                                    ctl2, ctl3, ctl4,None])
533                        self.orientation_params_disp.append([cb,name1,ctl1,text2,
534                                                    ctl2, ctl3, ctl4,None])
535                    elif p=="npts":
536                            ix = 6
537                            value= self.model.getParam(name2)
538                            Tctl = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20),
539                                                style=wx.TE_PROCESS_ENTER)
540                           
541                            Tctl.SetValue(str (format_number(value)))
542                            if self.data.__class__.__name__ =="Data2D":
543                                Tctl.Show(True)
544                            else:
545                                Tctl.Hide()
546                            self.sizer4_4.Add(Tctl, (iy,ix),(1,1),
547                                               wx.EXPAND|wx.ADJUST_MINSIZE, 0)
548                            self.fixed_param.append([None,name2, Tctl,None,None,
549                                                      None, None,None])
550                            self.orientation_params_disp.append([None,name2, Tctl,None,None,
551                                                      None, None,None])
552                    elif p=="nsigmas":
553                            ix = 7
554                            value= self.model.getParam(name3)
555                            Tctl = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20),
556                                                style=wx.TE_PROCESS_ENTER)
557                            Tctl.SetValue(str (format_number(value)))
558                            if self.data.__class__.__name__ =="Data2D":
559                                Tctl.Show(True)
560                            else:
561                                Tctl.Hide()
562                            self.sizer4_4.Add(Tctl, (iy,ix),(1,1),
563                                               wx.EXPAND|wx.ADJUST_MINSIZE, 0)
564                            ix +=1
565                            #self.sizer4_4.Add((20,20), (iy,ix),(1,1),
566                                               #wx.EXPAND|wx.ADJUST_MINSIZE, 0)
567                            self.fixed_param.append([None,name3, Tctl
568                                                     ,None,None, None, None,None])   
569                                                       
570                            self.orientation_params_disp.append([None,name3, Tctl
571                                                     ,None,None, None, None,None])
572        #Display units text on panel
573        for item in self.model.dispersion.keys():   
574            if self.model.details[item][3]!= None and numpy.isfinite(self.model.details[item][3]):
575                if not self.text2_3.IsShown():
576                    self.text2_3.Show()
577                break
578            else:
579                self.text2_3.Hide()
580   
581        self.state.disp_cb_dict = copy.deepcopy(self.disp_cb_dict)     
582        self.state.model = self.model.clone() 
583         ## save state into
584        self.state.cb1 = self.cb1.GetValue()
585        self._copy_parameters_state(self.parameters, self.state.parameters)
586        self._copy_parameters_state(self.orientation_params_disp,
587                                     self.state.orientation_params_disp)
588        self._copy_parameters_state(self.fittable_param, self.state.fittable_param)
589        self._copy_parameters_state(self.fixed_param, self.state.fixed_param)
590
591
592        wx.PostEvent(self.parent, StatusEvent(status=\
593                        " Selected Distribution: Gaussian"))   
594        ix =0
595        iy +=1 
596        self.sizer4_4.Layout()
597        self.sizer4.Layout()
598        self.Layout()
599        self.SetScrollbars(20,20,25,65)
600        self.Refresh()
601     
602       
603    def _onFit(self, event):     
604        """
605            Allow to fit
606        """
607        from sans.guiframe.utils import check_value
608        self.select_param(event =None)
609        flag = check_value( self.qmin, self.qmax) 
610               
611        if not flag:
612            msg= "Fitting range invalid"
613            wx.PostEvent(self.parent.parent, StatusEvent(status= msg ))
614            return 
615       
616        if len(self.param_toFit) <= 0:
617            msg= "Select at least one parameter to fit"
618            wx.PostEvent(self.parent.parent, StatusEvent(status= msg ))
619            return 
620       
621        #Clear errors if exist from previous fitting
622        self._clear_Err_on_Fit()   
623
624        # Remove or do not allow fitting on the Q=0 point, especially when y(q=0)=None at x[0].
625        #ToDo: Fix this.               
626        self.qmin_x = float(self.qmin.GetValue())
627        self.qmax_x =float( self.qmax.GetValue())
628        self.manager._reset_schedule_problem( value=0)
629        self.manager.schedule_for_fit( value=1,page=self,fitproblem =None) 
630        self.manager.set_fit_range(page= self,qmin= self.qmin_x, qmax= self.qmax_x)
631       
632        #single fit
633        self.manager.onFit()
634        ## allow stopping the fit
635        #if self.engine_type=="scipy":
636        #    self.btFit.SetLabel("Stop")
637        #    self.btFit.Unbind(event=wx.EVT_BUTTON, id= self.btFit.GetId())
638        #    self.btFit.Bind(event= wx.EVT_BUTTON, handler=self._StopFit, id=self.btFit.GetId())
639        #else:
640        #    self.btFit.SetLabel("Fit")
641        #    self.btFit.Bind(event= wx.EVT_BUTTON, handler=self._onFit, id=self.btFit.GetId())
642        self.btFit.SetFocus()   
643
644       
645    def _StopFit(self, event):
646        """
647            Stop fit
648        """
649        self.btFit.SetLabel("Fit")
650        if self.engine_type=="scipy":
651            self.manager.stop_fit()
652        self.btFit.Unbind(event=wx.EVT_BUTTON, id=self.btFit.GetId())
653        self.btFit.Bind(event=wx.EVT_BUTTON, handler=self._onFit,id=self.btFit.GetId())
654       
655           
656        #self.btFit.SetFocus()   
657        #self.sizer5.Layout()
658        #self.SetScrollbars(20,20,55,40)   
659           
660    def _on_select_model(self, event): 
661        """
662             call back for model selection
663        """   
664        self._on_select_model_helper() 
665        self.set_model_param_sizer(self.model)                   
666       
667        self.enable_disp.SetValue(False)
668        self.disable_disp.SetValue(True)
669        try:
670            self.set_dispers_sizer()
671        except:
672            pass
673        if self.model !=None:
674            try:
675                temp_smear= None
676                if self.enable_smearer.GetValue():
677                    temp_smear= self.smearer
678                self.compute_chisqr(temp_smear)
679            except:
680                ## error occured on chisqr computation
681                pass
682            ## set smearing value whether or not the data contain the smearing info
683            self.manager.set_smearer(smearer=temp_smear, qmin= float(self.qmin_x),
684                                     qmax= float(self.qmax_x)) 
685            evt = ModelEventbox(model=self.model)
686            wx.PostEvent(self.event_owner, evt) 
687           
688        self.btFit.SetFocus() 
689        self.state.enable_disp = self.enable_disp.GetValue()
690        self.state.disable_disp = self.disable_disp.GetValue()
691   
692        self.state.structurecombobox = self.structurebox.GetCurrentSelection()
693        self.state.formfactorcombobox = self.formfactorbox.GetCurrentSelection()
694     
695       
696        if event !=None:
697            #self._undo.Enable(True)
698            ## post state to fit panel
699            event = PageInfoEvent(page = self)
700            wx.PostEvent(self.parent, event) 
701     
702   
703    def _onparamRangeEnter(self, event):
704        """
705            Check validity of value enter in the parameters range field
706        """
707        tcrtl= event.GetEventObject()
708        if tcrtl.GetValue().lstrip().rstrip()!="":
709
710            try:
711                value = float(tcrtl.GetValue())
712                tcrtl.SetBackgroundColour(wx.WHITE)
713                tcrtl.Refresh()
714            except:
715                tcrtl.SetBackgroundColour("pink")
716                tcrtl.Refresh()
717                return
718        else:
719           tcrtl.SetBackgroundColour(wx.WHITE)
720           tcrtl.Refresh() 
721        self._onparamEnter_helper() 
722       
723        ##compute chisqr for range change
724        temp_smearer = None
725        if self.enable_smearer.GetValue():
726            msg=""
727            temp_smearer= self.smearer   
728         ##Calculate chi2
729       
730        self.compute_chisqr(smearer= temp_smearer) 
731        ## new state posted
732        if self.state_change:
733            #self._undo.Enable(True)
734            event = PageInfoEvent(page = self)
735            wx.PostEvent(self.parent, event)
736            self.state_change= False
737       
738       
739    def _onparamEnter(self,event):
740        """
741            when enter value on panel redraw model according to changed
742        """
743        tcrtl= event.GetEventObject()
744
745        if check_float(tcrtl):
746            self._onparamEnter_helper()
747           
748            temp_smearer = None
749            if self.enable_smearer.GetValue():
750                temp_smearer= self.smearer
751            self.compute_chisqr(smearer= temp_smearer)
752
753            ## new state posted
754            if self.state_change:
755                #self._undo.Enable(True)
756                event = PageInfoEvent(page = self)
757                wx.PostEvent(self.parent, event)
758                self.state_change= False
759        else:
760            msg= "Cannot Plot :Must enter a number!!!  "
761            wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
762            return 
763       
764    ### Same as _onparamRangeEnter but smear and chi^2 calculations are removed
765    ### and _onparamEnter_helper is not used, which causing mess sizer display
766    def _on_paramRangeEnter(self, event):
767        """
768            Check validity of value enter in the parameters range field
769        """
770        tcrtl= event.GetEventObject()
771        if tcrtl.GetValue().lstrip().rstrip()!="":
772            try:
773                value = float(tcrtl.GetValue())
774                tcrtl.SetBackgroundColour(wx.WHITE)
775                tcrtl.Refresh()
776            except:
777                tcrtl.SetBackgroundColour("pink")
778                tcrtl.Refresh()
779                return
780        else:
781           tcrtl.SetBackgroundColour(wx.WHITE)
782           tcrtl.Refresh() 
783        self._onparamEnter_helper() 
784
785        ## new state posted
786        if self.state_change:
787            #self._undo.Enable(True)
788            event = PageInfoEvent(page = self)
789            wx.PostEvent(self.parent, event)
790            self.state_change= False
791       
792               
793       
794    def set_data(self, data ):
795        """
796            reset the current data
797        """
798        if data ==None:
799            return 
800        self.data =data
801        self.state.data= data
802        self._fill_datainfo_sizer()
803        self.SetScrollbars(20,20,25,65)
804        self.Layout()   
805       
806    def reset_page(self, state,first=False):
807        """
808            reset the state
809        """
810        import sans.guiframe.gui_manager
811       
812        self.reset_page_helper(state)
813        evt = ModelEventbox(model=state.model)
814        wx.PostEvent(self.event_owner, evt)
815        self.manager._on_change_engine(engine=self.engine_type)
816        #Not improving anything yet.
817        #self.set_model_param_sizer(model=state.model)
818           
819    def get_range(self):
820        """
821            return the fitting range
822        """
823        return float(self.qmin_x) , float(self.qmax_x)
824       
825    def get_param_list(self):
826        """
827            @return self.param_toFit: list containing  references to TextCtrl
828            checked.Theses TextCtrl will allow reference to parameters to fit.
829            @raise: if return an empty list of parameter fit will nnote work
830            properly so raise ValueError,"missing parameter to fit"
831        """
832        if self.param_toFit !=[]:
833            return self.param_toFit
834        else:
835            raise ValueError,"missing parameter to fit"   
836     
837    def onsetValues(self,chisqr,p_name, out,cov):
838        """
839            Build the panel from the fit result
840            @param chisqr:Value of the goodness of fit metric
841            @p_name: the name of parameters
842            @param out:list of parameter with the best value found during fitting
843            @param cov:Covariance matrix
844       
845        """
846        self.tcChi.SetLabel(format_number(chisqr))
847        params = {}
848        is_modified = False
849        has_error = False
850        try:
851            n = self.disp_box.GetCurrentSelection()
852            dispersity= self.disp_box.GetClientData(n)
853            name= dispersity.__name__
854            if name == "GaussianDispersion":
855                if hasattr(self,"text_disp_1" ):
856                    if self.text_disp_1 !=None:
857                        self.text_disp_1.Hide()
858        except:
859            pass
860        #set the panel when fit result are float not list
861        if out.__class__== numpy.float64:
862            print "float64"
863            self.param_toFit[0][2].SetValue(format_number(out))
864            self.param_toFit[0][2].Refresh()
865           
866            self.param_toFit[0][4].Clear()
867            self.param_toFit[0][4].Hide()
868            if cov !=None :
869                self.text2_3.Show(True)
870                try:
871                    name= dispersity.__name__
872                    if name == "GaussianDispersion":
873                        if hasattr(self,"text_disp_1" ):
874                            if self.text_disp_1 !=None:
875                                self.text_disp_1.Show(True)
876                except:
877                    pass
878
879                if cov[0]==None or  not numpy.isfinite(cov[0]): 
880                    self.param_toFit[0][3].Hide()
881                    self.param_toFit[0][4].Clear()
882                    #self.param_toFit[0][4].Hide()
883                    self.param_toFit[0][4].Refresh()
884                else:
885                    self.param_toFit[0][3].Show(True)
886                    self.param_toFit[0][4].Clear()
887                    self.param_toFit[0][4].SetValue(format_number(cov[0]))
888                    self.param_toFit[0][4].Show(True)
889                    self.param_toFit[0][4].Refresh()
890        else:
891            i=0
892            j=0
893            k=0
894           
895            if self.text2_3.IsShown():
896                self.text2_3.Hide()
897               
898            #Set the panel when fit result are list
899            for item in self.param_toFit:               
900                ## reset error value to initial state
901                if item[3].IsShown():
902                    item[3].Hide()
903                if item[4].IsShown():
904                    item[4].Hide()
905       
906                if( out != None ) and len(out)<=len(self.param_toFit)and i < len(out):
907                    item[2].SetValue(format_number(self.model.getParam(item[1])))
908                    item[2].Refresh()
909
910                if(cov !=None)  and len(cov)<=len(self.param_toFit)and i < len(cov):
911                    try:
912                        name= dispersity.__name__
913                        if name == "GaussianDispersion":
914                            if hasattr(self,"text_disp_1" ):
915                                if self.text_disp_1!=None:
916                                    self.text_disp_1.Show(True)
917                    except:
918                        pass                   
919                    for j in range(len(out)):
920                       
921                        if item[1] == p_name[j]:
922                            break
923                        ## unable to compare cov[j]==numpy.nan so switch to None
924                    #Save errors to model.details[item][3]
925                    self.model.details[item[1]][3] = cov[j]
926                                                           
927                    if cov[j]==None or not numpy.isfinite(cov[j]):
928
929                        if item[3].IsShown:
930                            item[3].Hide()
931                        if item[4].IsShown:
932                            item[4].Hide()           
933                        #k += 1   
934
935                    else:
936                        k += 1
937                        item[3].Show(True)
938                        item[3].Refresh()
939                        item[4].Show(True)
940                        item[4].SetValue(format_number(cov[j]))
941                        item[4].Refresh()
942                   
943 
944                i+=1 
945        #Show error title when any errors displayed
946        if k != 0: # len(self.param_toFit):
947            if not self.text2_3.IsShown():
948                self.text2_3.Show(True)                           
949
950        self.text2_3.Refresh()             
951        self.Layout()
952       
953       
954    def onSmear(self, event):
955        """
956            Create a smear object that will change the way residuals
957            are compute when fitting
958        """
959        if self.model ==None:
960            msg="Need model and data to smear plot"
961            wx.PostEvent(self.manager.parent, StatusEvent(status=\
962                            "Smear: %s"%msg))
963            return
964        temp_smearer = None
965        if self.enable_smearer.GetValue():
966            temp_smearer= self.smearer
967            if hasattr(self.data,"dxl"):
968                msg= ": Resolution smearing parameters"
969            if hasattr(self.data,"dxw"):
970                msg= ": Slit smearing parameters"
971            if self.smearer ==None:
972                wx.PostEvent(self.manager.parent, StatusEvent(status=\
973                            "Data contains no smearing information"))
974            else:
975                wx.PostEvent(self.manager.parent, StatusEvent(status=\
976                            "Data contains smearing information %s"%msg))
977       
978        ## set smearing value whether or not the data contain the smearing info
979        self.manager.set_smearer(smearer=temp_smearer, qmin= float(self.qmin_x),
980                                     qmax= float(self.qmax_x)) 
981        ##Calculate chi2
982        self.compute_chisqr(smearer= temp_smearer) 
983       
984        self.state.enable_smearer=  self.enable_smearer.GetValue()
985        self.state.disable_smearer=self.disable_smearer.GetValue()
986   
987    def complete_chisqr(self, output, elapsed=None): 
988        """
989            print result chisqr
990        """
991        try:
992            if output ==None:
993                output= "-"
994            self.tcChi.SetLabel(str(format_number(output)))
995           
996            self.sizer5.Layout()
997            self.state.tcChi =output
998         
999        except:
1000            pass
1001       
1002       
1003    def compute_chisqr1D(self, smearer=None):
1004        """
1005            Compute chisqr for 1D
1006        """
1007        from sans.guiframe.utils import check_value
1008        flag = check_value( self.qmin, self.qmax)
1009       
1010        if not flag:
1011            return 
1012       
1013        try:
1014            self.qmin_x = float(self.qmin.GetValue())
1015            self.qmax_x = float(self.qmax.GetValue())
1016            ##return residuals within self.qmin_x and self.qmax_x
1017            from gui_thread import CalcChisqr1D
1018            ## If a thread is already started, stop it
1019            if self.calc_Chisqr!= None and self.calc_Chisqr.isrunning():
1020                self.calc_Chisqr.stop()
1021               
1022            self.calc_Chisqr= CalcChisqr1D( data1d= self.data,
1023                                            model= self.model,
1024                                            smearer=smearer,
1025                                            qmin=self.qmin_x,
1026                                            qmax=self.qmax_x,
1027                                            completefn = self.complete_chisqr,
1028                                            updatefn   = None)
1029   
1030            self.calc_Chisqr.queue()
1031           
1032        except:
1033            raise ValueError," Could not compute Chisqr for %s Model 2D: "%self.model.name
1034           
1035           
1036   
1037       
1038       
1039    def compute_chisqr2D(self):
1040        """
1041            compute chi square given a model and data 2D and set the value
1042            to the tcChi txtcrl
1043        """
1044        from sans.guiframe.utils import check_value
1045        flag = check_value( self.qmin, self.qmax)
1046        if not flag:
1047            return 
1048     
1049        try:
1050            self.qmin_x = float(self.qmin.GetValue())
1051            self.qmax_x = float(self.qmax.GetValue())
1052           
1053            ##return residuals within self.qmin_x and self.qmax_x
1054            from gui_thread import CalcChisqr2D
1055            ## If a thread is already started, stop it
1056            if self.calc_Chisqr!= None and self.calc_Chisqr.isrunning():
1057                self.calc_Chisqr.stop()
1058           
1059            self.calc_Chisqr= CalcChisqr2D( data2d= self.data,
1060                                            model= self.model,
1061                                            qmin= self.qmin_x,
1062                                            qmax = self.qmax_x,
1063                                            completefn = self.complete_chisqr,
1064                                            updatefn   = None)
1065   
1066            self.calc_Chisqr.queue()
1067         
1068        except:
1069           raise
1070
1071       
1072    def compute_chisqr(self , smearer=None):
1073        """
1074            compute chi square given a model and data 1D and set the value
1075            to the tcChi txtcrl
1076        """
1077        from sans.guiframe.utils import check_value
1078        flag = check_value( self.qmin, self.qmax)
1079        if flag== True:
1080            try:
1081                if hasattr(self.data,"data"):
1082                    self.compute_chisqr2D()
1083                    return
1084                else:
1085                    self.compute_chisqr1D(smearer=smearer)
1086                    return
1087            except:
1088                wx.PostEvent(self.parent.parent, StatusEvent(status=\
1089                            "Chisqr Error: %s"% sys.exc_value))
1090                return 
1091           
1092   
1093    def select_all_param(self,event): 
1094        """
1095             set to true or false all checkBox given the main checkbox value cb1
1096        """           
1097
1098        self.param_toFit=[]
1099        if  self.parameters !=[]:
1100            if  self.cb1.GetValue():
1101                for item in self.parameters:
1102                    ## for data2D select all to fit
1103                    if self.data.__class__.__name__=="Data2D":
1104                        item[0].SetValue(True)
1105                        self.param_toFit.append(item )
1106                    else:
1107                        ## for 1D all parameters except orientation
1108                        if not item in self.orientation_params:
1109                            item[0].SetValue(True)
1110                            self.param_toFit.append(item )
1111                if len(self.fittable_param)>0:
1112                    for item in self.fittable_param:
1113                        if self.data.__class__.__name__=="Data2D":
1114                            item[0].SetValue(True)
1115                            self.param_toFit.append(item )
1116                        else:
1117                            ## for 1D all parameters except orientation
1118                            if not item in self.orientation_params_disp:
1119                                item[0].SetValue(True)
1120                                self.param_toFit.append(item )
1121            else:
1122                for item in self.parameters:
1123                    item[0].SetValue(False)
1124                for item in self.fittable_param:
1125                    item[0].SetValue(False)
1126                self.param_toFit=[]
1127           
1128        self.save_current_state_fit() 
1129        if event !=None:
1130            #self._undo.Enable(True)
1131            ## post state to fit panel
1132            event = PageInfoEvent(page = self)
1133            wx.PostEvent(self.parent, event) 
1134     
1135               
1136               
1137    def select_param(self,event):
1138        """
1139            Select TextCtrl  checked for fitting purpose and stores them
1140            in  self.param_toFit=[] list
1141        """
1142        self.param_toFit=[]
1143        for item in self.parameters:
1144            #Select parameters to fit for list of primary parameters
1145            if item[0].GetValue():
1146                if not (item in self.param_toFit):
1147                    self.param_toFit.append(item ) 
1148            else:
1149                #remove parameters from the fitting list
1150                if item in self.param_toFit:
1151                    self.param_toFit.remove(item)
1152        #Select parameters to fit for list of fittable parameters with dispersion         
1153        for item in self.fittable_param:
1154            if item[0].GetValue():
1155                if not (item in self.param_toFit):
1156                    self.param_toFit.append(item) 
1157            else:
1158                #remove parameters from the fitting list
1159                if item in self.param_toFit:
1160                    self.param_toFit.remove(item)           
1161        #Set the value of checkbox that selected every checkbox or not           
1162        if len(self.parameters)+len(self.fittable_param) ==len(self.param_toFit):
1163            self.cb1.SetValue(True)
1164        else:
1165            self.cb1.SetValue(False)
1166        self.save_current_state_fit()
1167        if event !=None:
1168            #self._undo.Enable(True)
1169            ## post state to fit panel
1170            event = PageInfoEvent(page = self)
1171            wx.PostEvent(self.parent, event) 
1172     
1173   
1174       
1175    def set_model_param_sizer(self, model):
1176        """
1177            Build the panel from the model content
1178            @param model: the model selected in combo box for fitting purpose
1179        """
1180        self.sizer3.Clear(True)
1181        self.parameters = []
1182        self.param_toFit=[]
1183        self.fittable_param=[]
1184        self.fixed_param=[]
1185        self.orientation_params=[]
1186        self.orientation_params_disp=[]
1187       
1188        if model ==None:
1189            self.sizer3.Layout()
1190            self.SetScrollbars(20,20,25,65)
1191            return
1192        ## the panel is drawn using the current value of the fit engine
1193        if self.engine_type==None and self.manager !=None:
1194            self.engine_type= self.manager._return_engine_type()
1195
1196           
1197        box_description= wx.StaticBox(self, -1,str("Model Parameters"))
1198        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
1199        sizer = wx.GridBagSizer(5,5)
1200        ## save the current model
1201        self.model = model
1202           
1203        keys = self.model.getParamList()
1204        #list of dispersion paramaters
1205        self.disp_list=self.model.getDispParamList()
1206       
1207        keys.sort()
1208   
1209        iy = 0
1210        ix = 0
1211        self.cb1 = wx.CheckBox(self, -1,"Select all", (10, 10))
1212        wx.EVT_CHECKBOX(self, self.cb1.GetId(), self.select_all_param)
1213        self.cb1.SetValue(False)
1214       
1215        sizer.Add(self.cb1,(iy, ix),(1,1),\
1216                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)
1217        ix +=1
1218        self.text2_2 = wx.StaticText(self, -1, 'Values')
1219        sizer.Add(self.text2_2,(iy, ix),(1,1),\
1220                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1221        ix +=2 
1222        self.text2_3 = wx.StaticText(self, -1, 'Errors')
1223        sizer.Add(self.text2_3,(iy, ix),(1,1),\
1224                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
1225        self.text2_3.Hide()
1226        ix +=1 
1227        self.text2_min = wx.StaticText(self, -1, 'Min')
1228        sizer.Add(self.text2_min,(iy, ix),(1,1),\
1229                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
1230        self.text2_min.Hide()
1231        ix +=1 
1232        self.text2_max = wx.StaticText(self, -1, 'Max')
1233        sizer.Add(self.text2_max,(iy, ix),(1,1),\
1234                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
1235        self.text2_max.Hide()
1236        ix += 1
1237        self.text2_4 = wx.StaticText(self, -1, '[Units]')
1238        sizer.Add(self.text2_4,(iy, ix),(1,1),\
1239                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
1240        self.text2_4.Hide()
1241        if self.engine_type=="park":
1242            self.text2_max.Show(True)
1243            self.text2_min.Show(True)
1244
1245        for item in keys:
1246            if not item in self.disp_list and not item in self.model.orientation_params:
1247                ##prepare a spot for error
1248                if len(self.model.details[item])<4:
1249                    self.model.details[item].append(numpy.nan)               
1250                iy += 1
1251                ix = 0
1252                ## add parameters name with checkbox for selecting to fit
1253                cb = wx.CheckBox(self, -1, item )
1254                cb.SetValue(False)
1255                wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param)
1256                sizer.Add( cb,( iy, ix),(1,1),
1257                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)
1258               
1259                ## add parameter value
1260                ix += 1
1261                value= self.model.getParam(item)
1262                ctl1 = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH,20),
1263                                    style=wx.TE_PROCESS_ENTER)
1264               
1265                ctl1.SetValue(format_number(value))
1266                sizer.Add(ctl1, (iy,ix),(1,1), wx.EXPAND)
1267                ## text to show error sign
1268                ix += 1
1269                text2=wx.StaticText(self, -1, '+/-')
1270                sizer.Add(text2,(iy, ix),(1,1),\
1271                                wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
1272                text2.Hide() 
1273                ## txtcrtl to add error from fit
1274                fit_errs = self.model.details[item][3]
1275
1276                ix += 1
1277                ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER)
1278
1279               
1280                ctl2.SetValue(str(format_number(fit_errs)))
1281                sizer.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1282                if fit_errs==None or not numpy.isfinite(fit_errs):                   
1283                    ctl2.Hide()
1284                else:
1285                    if not self.text2_3.IsShown():
1286                        self.text2_3.Show(True)
1287                    if not text2.IsShown():
1288                        text2.Show(True) 
1289                    ctl2.Show(True)
1290               
1291                param_min, param_max= self.model.details[item][1:3]
1292                ix += 1
1293                ctl3 = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
1294                                               kill_focus_callback = self._on_paramRangeEnter,
1295                                               set_focus_callback  = self._on_paramRangeEnter)
1296                if param_min ==None or not numpy.isfinite(param_min):
1297                    ctl3.SetValue("")
1298                else:
1299                    ctl3.SetValue(str(param_min))
1300                sizer.Add(ctl3, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1301                ctl3.Hide()
1302       
1303                ix += 1
1304                ctl4 = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
1305                                               kill_focus_callback = self._on_paramRangeEnter,
1306                                               set_focus_callback  = self._on_paramRangeEnter)
1307                sizer.Add(ctl4, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1308                if param_max==None or not numpy.isfinite(param_max):
1309                    ctl4.SetValue("")
1310                else:
1311                    ctl4.SetValue(str(param_max))
1312                ctl4.Hide()
1313               
1314                if self.engine_type=="park":
1315                    ctl3.Show(True)
1316                    ctl4.Show(True)
1317                ix +=1
1318                # Units
1319                try:
1320                    units = wx.StaticText(self, -1, self.model.details[item][0], style=wx.ALIGN_LEFT)
1321                except:
1322                    units = wx.StaticText(self, -1, "", style=wx.ALIGN_LEFT)
1323                sizer.Add(units, (iy,ix),(1,1),  wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1324                   
1325                ##[cb state, name, value, "+/-", error of fit, min, max , units]
1326                self.parameters.append([cb,item, ctl1,
1327                                        text2,ctl2, ctl3, ctl4,units])
1328             
1329        iy+=1
1330        sizer.Add((10,10),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1331       
1332        # type can be either Guassian or Array
1333        if len(self.model.dispersion.values())>0:
1334            type= self.model.dispersion.values()[0]["type"]
1335        else:
1336            type = "Gaussian"
1337           
1338        iy += 1
1339        ix = 0
1340        #Add tile for orientational angle
1341        for item in keys:
1342            if item in self.model.orientation_params:       
1343                orient_angle = wx.StaticText(self, -1, '[For 2D only]:')
1344                sizer.Add(orient_angle,(iy, ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15) 
1345                if not self.data.__class__.__name__ =="Data2D":
1346                    orient_angle.Hide()
1347                else:
1348                    orient_angle.Show(True)
1349                break
1350     
1351        #For Gaussian only
1352        if type.lower() != "array":
1353            for item in self.model.orientation_params:
1354                if not item in self.disp_list:
1355                    if len(self.model.details[item])<4:
1356                        self.model.details[item].append(numpy.nan)   
1357                    iy += 1
1358                    ix = 0
1359                    ## add parameters name with checkbox for selecting to fit
1360                    cb = wx.CheckBox(self, -1, item )
1361                    cb.SetValue(False)
1362                    wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param)
1363                    if self.data.__class__.__name__ =="Data2D":
1364                        cb.Show(True)
1365                    else:
1366                        cb.Hide()
1367                    sizer.Add( cb,( iy, ix),(1,1),
1368                                 wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)
1369   
1370                    ## add parameter value
1371                    ix += 1
1372                    value= self.model.getParam(item)
1373                    ctl1 = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH,20),
1374                                        style=wx.TE_PROCESS_ENTER)
1375                   
1376                    ctl1.SetValue(format_number(value))
1377                    if self.data.__class__.__name__ =="Data2D":
1378                        ctl1.Show(True)
1379                    else:
1380                        ctl1.Hide()
1381                    sizer.Add(ctl1, (iy,ix),(1,1), wx.EXPAND)
1382                    ## text to show error sign
1383                    ix += 1
1384                    text2=wx.StaticText(self, -1, '+/-')
1385                    sizer.Add(text2,(iy, ix),(1,1),\
1386                                    wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
1387                    text2.Hide() 
1388                    ## txtcrtl to add error from fit
1389                    fit_errs = self.model.details[item][3]
1390                    ix += 1
1391                    ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER)
1392                    ctl2.SetValue(str(format_number(fit_errs)))
1393                    sizer.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1394                    ctl2.Hide()
1395                    if self.data.__class__.__name__ !="Data2D":
1396                            ctl2.Hide()
1397                    else:
1398                        if fit_errs!=None and numpy.isfinite(fit_errs):
1399                            if not text2.IsShown():
1400                                text2.Show(True)
1401                            ctl2.Show(True)
1402                   
1403                    param_min, param_max= self.model.details[item][1:3]
1404                    ix += 1
1405                    ctl3 = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
1406                                                   kill_focus_callback = self._onparamRangeEnter,
1407                                                   set_focus_callback  = self._onparamRangeEnter)
1408                    if param_min ==None or not numpy.isfinite(param_min):
1409                        ctl3.SetValue("")
1410                    else:
1411                        ctl3.SetValue(str(param_min))
1412                    sizer.Add(ctl3, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1413                    ctl3.Hide()
1414                    if self.data.__class__.__name__ =="Data2D":
1415                        ctl3.Show(True)
1416                     
1417                    else:
1418                        ctl3.Hide()
1419               
1420                    ix += 1
1421                    ctl4 = BasicPage.ModelTextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER,
1422                                                   kill_focus_callback = self._onparamRangeEnter,
1423                                                   set_focus_callback  = self._onparamRangeEnter)
1424                    sizer.Add(ctl4, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1425                    if param_max ==None or not numpy.isfinite(param_max):
1426                        ctl4.SetValue("")
1427                    else:
1428                        ctl4.SetValue(str(param_max))
1429                    ctl4.Hide()
1430                    if self.data.__class__.__name__ =="Data2D":
1431                        ctl4.Show(True)
1432                 
1433                    else:
1434                        ctl4.Hide()
1435                   
1436                    if self.engine_type !="park" or self.data.__class__.__name__ !="Data2D":                     
1437                        ctl3.Hide()
1438                        ctl4.Hide()
1439                    else:
1440                        ctl3.Show(True)
1441                        ctl4.Show(True)
1442                   
1443                    ix +=1
1444                    # Units
1445                    try:
1446                        units = wx.StaticText(self, -1, self.model.details[item][0], style=wx.ALIGN_LEFT)
1447                    except:
1448                        units = wx.StaticText(self, -1, "", style=wx.ALIGN_LEFT)
1449                    if self.data.__class__.__name__ =="Data2D":
1450                        units.Show(True)
1451                   
1452                    else:
1453                        units.Hide()
1454                   
1455                    sizer.Add(units, (iy,ix),(1,1),  wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1456                       
1457                   
1458                    ##[cb state, name, value, "+/-", error of fit, min, max , units]
1459                    self.parameters.append([cb,item, ctl1,
1460                                            text2,ctl2, ctl3, ctl4,units])
1461                    self.orientation_params.append([cb,item, ctl1,
1462                                            text2,ctl2, ctl3, ctl4,units])
1463             
1464        iy+=1
1465        #sizer.Add((10,10),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1466       
1467        #Display units text on panel
1468        for item in keys:   
1469            if self.model.details[item][0]!='':
1470                self.text2_4.Show()
1471                break
1472            else:
1473                self.text2_4.Hide()
1474        #self.state.cb1 = self.cb1.GetValue()       
1475        #self._copy_parameters_state(self.orientation_params,
1476        #                             self.state.orientation_params)
1477        #self._copy_parameters_state(self.orientation_params_disp,
1478        #                             self.state.orientation_params_disp)
1479        #self._copy_parameters_state(self.parameters, self.state.parameters)
1480        #self._copy_parameters_state(self.fittable_param, self.state.fittable_param)
1481        #self._copy_parameters_state(self.fixed_param, self.state.fixed_param)
1482        self.save_current_state_fit()
1483        boxsizer1.Add(sizer)
1484        self.sizer3.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10)
1485        self.sizer3.Layout()
1486        self.Layout()
1487        self.Refresh()
1488        self.SetScrollbars(20,20,25,65)
1489
1490
1491       
1492class HelpWindow(wx.Frame):
1493    def __init__(self, parent, id, title):
1494        wx.Frame.__init__(self, parent, id, title, size=(570, 400))
1495       
1496        from sans.models.CylinderModel import CylinderModel
1497        model = CylinderModel()
1498       
1499        from danse.common.plottools.plottables import Data1D
1500        data= Data1D(x=[1,2], y=[3,4], dy=[0.1, 0,1])
1501   
1502        from fitpanel import PageInfo
1503        myinfo = PageInfo(self,  model, data=data )
1504       
1505        ## add data
1506       
1507        from models import ModelList
1508        mylist= ModelList()
1509
1510        from sans.models.SphereModel import SphereModel
1511        from sans.models.SquareWellStructure import SquareWellStructure
1512        from sans.models.DebyeModel import DebyeModel
1513        from sans.models.LineModel import LineModel
1514        name= "shapes"
1515        list1= [SphereModel]
1516        mylist.set_list( name, list1)
1517       
1518        name= "Shape-independent"
1519        list1= [DebyeModel]
1520        mylist.set_list( name, list1)
1521       
1522        name= "Structure Factors"
1523        list1= [SquareWellStructure]
1524        mylist.set_list( name, list1)
1525       
1526        name= "Added models"
1527        list1= [LineModel]
1528        mylist.set_list( name, list1)
1529       
1530        myinfo.model_list_box = mylist.get_list()
1531       
1532        self.page = FitPage(self, myinfo) 
1533       
1534       
1535       
1536        self.Centre()
1537        self.Show(True)
1538
1539
1540   
1541if __name__=="__main__":
1542    app = wx.App()
1543    HelpWindow(None, -1, 'HelpWindow')
1544    app.MainLoop()
1545               
Note: See TracBrowser for help on using the repository browser.