source: sasview/sansview/perspectives/fitting/fitpage.py @ d23528ee

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

cleaned up.

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