source: sasview/sansview/perspectives/fitting/fitpage.py @ 3bb37ef

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

fixed not properly displaying error bars and fit_engine_types on resetting fit pages from bookmarks (also some minor fixes for mac)

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