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

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 bdd71f4 was ca7a626, checked in by Gervaise Alina <gervyh@…>, 15 years ago

combine single fit and simultaneous fit

  • Property mode set to 100644
File size: 33.8 KB
Line 
1import sys
2import wx
3import wx.lib.newevent
4import numpy
5import copy
6import math
7from sans.models.dispersion_models import ArrayDispersion, GaussianDispersion
8
9from sans.guicomm.events import StatusEvent   
10from sans.guiframe.utils import format_number
11(ModelEventbox, EVT_MODEL_BOX) = wx.lib.newevent.NewEvent()
12_BOX_WIDTH = 80
13
14import basepage
15from basepage import BasicPage
16
17
18class FitPage(BasicPage):
19    """
20        FitPanel class contains fields allowing to display results when
21        fitting  a model and one data
22        @note: For Fit to be performed the user should check at least one parameter
23        on fit Panel window.
24 
25    """
26    def __init__(self,parent, page_info, name=""):
27        BasicPage.__init__(self, parent, page_info,name)
28        """
29            Initialization of the Panel
30        """
31        ## fit page does not content npts txtcrtl
32        self.npts=None
33        ## if no dispersity parameters is avaible
34        self.text_disp_1=None
35       
36        self._fill_datainfo_sizer()
37        self._fill_model_sizer( self.sizer1)
38        self._fill_range_sizer() 
39        if hasattr(self.page_info,"model"):
40            self.set_model_param_sizer(self.model)
41           
42       
43    def _on_display_description(self, event):
44        """
45            Show or Hide description
46            @param event: wx.EVT_RADIOBUTTON
47        """
48        self._on_display_description_helper()
49       
50       
51       
52    def _on_display_description_helper(self):
53        """
54            Show or Hide description
55            @param event: wx.EVT_RADIOBUTTON
56        """
57        ## save state of radiobox
58        self.page_info. save_radiobox_state( self.description_hide )
59        self.page_info. save_radiobox_state( self.description_show )
60        ## Show description
61        if not self.description_show.GetValue():
62            self.sizer_description.Clear(True)
63           
64        else:
65            model=self.page_info.model
66            description=""
67            if model!=None:
68                description = self.page_info.model.description
69            self.description = wx.StaticText( self,-1,str(description) )
70            self.sizer_description.Add( self.description, 1, wx.EXPAND | wx.ALL, 10 )
71           
72        self.Layout()
73   
74   
75    def _fill_range_sizer(self):
76        """
77            Fill the sizer containing the plotting range
78            add  access to npts
79        """
80        sizer_fit = wx.GridSizer(1, 1,0, 0)
81   
82        self.btFit = wx.Button(self,wx.NewId(),'Fit')
83        self.btFit.Bind(wx.EVT_BUTTON, self._onFit,id= self.btFit.GetId())
84        self.btFit.SetToolTipString("Perform fit.")
85       
86        #self.btStopFit = wx.Button(self,wx.NewId(),'Stop Fit')
87        #self.btStopFit.Bind(wx.EVT_BUTTON, self.onStopFit,id= self.btStopFit.GetId())
88        #self.btStopFit.SetToolTipString("Stop Current fit job.")
89        #self.btStopFit.Hide()
90       
91        sizer_fit.Add((5,5),1, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)       
92        sizer_fit.Add(self.btFit,0, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5) 
93        #sizer_fit.Add(self.btStopFit,1, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)
94       
95        sizer_smearer = wx.BoxSizer(wx.HORIZONTAL)
96        #Filling the sizer containing instruments smearing info.
97        self.disable_smearer = wx.RadioButton(self, -1, 'No', style=wx.RB_GROUP)
98        self.enable_smearer = wx.RadioButton(self, -1, 'Yes')
99        self.Bind(wx.EVT_RADIOBUTTON, self.onSmear, id=self.disable_smearer.GetId())
100        self.Bind(wx.EVT_RADIOBUTTON, self.onSmear, id=self.enable_smearer.GetId())
101       
102        sizer_smearer.Add(wx.StaticText(self,-1,'Instrument Smearing? '))
103        sizer_smearer.Add((10, 10))
104        sizer_smearer.Add( self.enable_smearer )
105        sizer_smearer.Add((10,10))
106        sizer_smearer.Add( self.disable_smearer )
107       
108        self._set_range_sizer( title="Fitted Q Range",
109                               object1=sizer_smearer, object= sizer_fit)
110       
111       
112    def _fill_datainfo_sizer(self):
113        """
114            fill sizer 0 with data info
115        """
116        self.sizer0.Clear(True)
117        ## no loaded data , don't fill the sizer
118        if self.data== None:
119            self.sizer0.Layout()
120            return
121       
122        box_description= wx.StaticBox(self, -1, 'Loaded Data')
123        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
124        #----------------------------------------------------------
125        sizer_data = wx.GridSizer(3, 3,5, 5)
126        #Filling the sizer containing data related fields
127        DataSource  =wx.StaticText(self, -1,str(self.data.name))
128
129        sizer_data.Add(wx.StaticText(self, -1, 'Data Source Name : '))
130        sizer_data.Add(DataSource )
131        sizer_data.Add( (5,5) )
132       
133        #---------sizer 2 draw--------------------------------
134        #set maximum range for x in linear scale
135        if not hasattr(self.data,"data"): #Display only for 1D data fit
136            # Minimum value of data   
137            data_min = str(format_number(numpy.min(self.data.x)))
138            # Maximum value of data 
139            data_max = str(format_number(numpy.max(self.data.x)))
140            text4_3 = wx.StaticText(self, -1, 'Maximum Q Range(Linear)',
141                                     style=wx.ALIGN_LEFT)
142            sizer_data.Add( text4_3 )
143            sizer_data.Add(wx.StaticText(self, -1, "Min : %s"%data_min))
144            sizer_data.Add(wx.StaticText(self, -1, "Max : %s"%data_max))
145           
146        else:
147            radius_min= 0
148            x= numpy.max(self.data.xmin, self.data.xmax)
149            y= numpy.max(self.data.ymin, self.data.ymax)
150            radius_max = math.sqrt(x*x + y*y)
151            # Minimum value of data   
152            data_min = str(format_number(radius_min))
153            # Maximum value of data 
154            data_max = str(format_number(radius_max))
155            text4_3 = wx.StaticText(self, -1, 'Maximum Q Range',
156                                     style=wx.ALIGN_LEFT)
157            sizer_data.Add( text4_3 )
158            sizer_data.Add(wx.StaticText(self, -1, "Min : %s"%data_min))
159            sizer_data.Add(wx.StaticText(self, -1, "Max : %s"%data_max))
160           
161        boxsizer1.Add(sizer_data)
162        #------------------------------------------------------------
163        self.sizer0.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10)
164        self.sizer0.Layout()
165       
166        self.qmin_x= data_min
167        self.qmax_x= data_max
168       
169    def _fill_model_sizer(self, sizer):
170        """
171            fill sizer containing model info
172        """
173        sizer_tcChi = wx.GridSizer(2, 2,5, 5)
174        self.tcChi    =  wx.StaticText(self, -1, str(0), style=wx.ALIGN_LEFT)
175        #self.tcChi.Hide()
176       
177        self.text1_1 = wx.StaticText(self, -1, 'Chi2/dof', style=wx.ALIGN_LEFT)
178        #self.text1_1.Hide()
179       
180        self.btChi = wx.Button(self,wx.NewId(),'View Chi')
181        self.btChi.Bind(wx.EVT_BUTTON, self._onFit,id= self.btChi.GetId())
182        self.btChi.SetToolTipString("View data - model.")
183       
184        sizer_tcChi.Add(self.text1_1,1, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)
185        sizer_tcChi.Add(self.btChi,1, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)       
186        sizer_tcChi.Add(self.tcChi,1, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)       
187        sizer_tcChi.Add((5,5),1, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 5)
188           
189        ## class base method  to add view 2d button   
190        self._set_model_sizer(sizer=sizer, title="Model",object=  sizer_tcChi )   
191   
192   
193    def _set_sizer_gaussian(self):
194        """
195            draw sizer with gaussian dispersity parameters
196        """
197        self.fittable_param=[]
198        self.fixed_param=[]
199        ##reset model dispersity to gaussian
200        self._reset_gaussian_dispers()
201       
202        self.sizer4_4.Clear(True)
203       
204        if self.model==None:
205            ##no model is selected
206            return
207        if not self.enable_disp.GetValue():
208            ## the user didn't select dispersity display
209            return 
210        ix=0
211        iy=1
212        disp = wx.StaticText(self, -1, 'Names')
213        self.sizer4_4.Add(disp,( iy, ix),(1,1), 
214                           wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
215        ix += 1 
216        values = wx.StaticText(self, -1, 'Values')
217        self.sizer4_4.Add(values,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
218        ix +=2 
219        self.text_disp_1 = wx.StaticText(self, -1, 'Errors')
220        self.sizer4_4.Add( self.text_disp_1,(iy, ix),(1,1),\
221                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
222        self.text_disp_1.Hide()
223        ix += 1 
224        npts = wx.StaticText(self, -1, 'Npts')
225        self.sizer4_4.Add(npts,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
226        ix += 1 
227        nsigmas = wx.StaticText(self, -1, 'Nsigmas')
228        self.sizer4_4.Add(nsigmas,( iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
229       
230        for item in self.model.dispersion.keys():
231            name1=item+".width"
232            name2=item+".npts"
233            name3=item+".nsigmas"
234            iy += 1
235            for p in self.model.dispersion[item].keys():
236   
237                if p=="width":
238                    ix = 0
239                    cb = wx.CheckBox(self, -1, name1, (10, 10))
240                    wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param)
241                   
242                    self.sizer4_4.Add( cb,( iy, ix),(1,1), 
243                                       wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
244                    ix = 1
245                    value= self.model.getParam(name1)
246                    ctl1 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20),
247                                        style=wx.TE_PROCESS_ENTER)
248                   
249                    ctl1.SetValue(str (format_number(value)))
250                    ctl1.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)
251                    ctl1.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter)
252                    self.sizer4_4.Add(ctl1, (iy,ix),(1,1),wx.EXPAND)
253                   
254                    ## text to show error sign
255                    ix = 2
256                    text2=wx.StaticText(self, -1, '+/-')
257                    self.sizer4_4.Add(text2,(iy, ix),(1,1),
258                                      wx.EXPAND|wx.ADJUST_MINSIZE, 0)
259                    text2.Hide() 
260                    ## txtcrtl to add error from fit
261                    ix = 3
262                    ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER)
263                    self.sizer4_4.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
264                    ctl2.Hide()
265                   
266                    self.fittable_param.append([cb,name1,ctl1,text2,
267                                                ctl2, None, None,None])
268                elif p=="npts":
269                        ix = 4
270                        value= self.model.getParam(name2)
271                        Tctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH/2,20),
272                                            style=wx.TE_PROCESS_ENTER)
273                       
274                        Tctl.SetValue(str (format_number(value)))
275                        Tctl.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)
276                        Tctl.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter)
277                        self.sizer4_4.Add(Tctl, (iy,ix),(1,1),
278                                           wx.EXPAND|wx.ADJUST_MINSIZE, 0)
279                       
280                        self.fixed_param.append([None,name2, Tctl,None,None,
281                                                  None, None,None])
282               
283                elif p=="nsigmas":
284                        ix = 5
285                        value= self.model.getParam(name3)
286                        Tctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH/2,20),
287                                            style=wx.TE_PROCESS_ENTER)
288                        Tctl.SetValue(str (format_number(value)))
289                        Tctl.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)
290                        Tctl.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter)
291                        self.sizer4_4.Add(Tctl, (iy,ix),(1,1),
292                                           wx.EXPAND|wx.ADJUST_MINSIZE, 0)
293                        ix +=1
294                        self.sizer4_4.Add((20,20), (iy,ix),(1,1),
295                                           wx.EXPAND|wx.ADJUST_MINSIZE, 0)
296                       
297                        self.fixed_param.append([None,name3, Tctl
298                                                 ,None,None, None, None,None])
299               
300        wx.PostEvent(self.parent, StatusEvent(status=\
301                        " Selected Distribution: Gaussian"))   
302        ix =0
303        iy +=1 
304        self.sizer4_4.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)       
305        self.sizer4_4.Layout()
306        self.sizer4.Layout()
307        self.SetScrollbars(20,20,200,100)
308     
309       
310    def _onFit(self, event):     
311        """
312            Allow to fit
313        """
314        #self.btFit.SetLabel("Stop")
315        from sans.guiframe.utils import check_value
316        flag = check_value( self.qmin, self.qmax) 
317       
318        if not flag:
319            msg= "Fitting range invalid"
320            wx.PostEvent(self.parent.parent, StatusEvent(status= msg ))
321            return 
322       
323        if len(self.param_toFit) <= 0:
324            msg= "Select at least one parameter to fit"
325            wx.PostEvent(self.parent.parent, StatusEvent(status= msg ))
326            return 
327       
328        self.qmin_x=float(self.qmin.GetValue())
329        self.qmax_x =float( self.qmax.GetValue())
330       
331        self.manager.schedule_for_fit( value=1,page=self,fitproblem =None) 
332        self.manager.set_fit_range(page= self,qmin= self.qmin_x, qmax= self.qmax_x)
333        #single fit
334        #self.manager.on_single_fit(qmin=self.qmin_x,qmax=self.qmax_x)
335        self.manager.onFit()
336           
337        self.sizer5.Layout()
338        self.SetScrollbars(20,20,55,40)
339       
340       
341    def _on_select_model(self, event): 
342        """
343             call back for model selection
344        """   
345        self._on_select_model_helper(event) 
346        self.set_model_param_sizer(self.model)
347        self._set_sizer_gaussian()
348       
349        evt = ModelEventbox(model=self.model)
350        wx.PostEvent(self.event_owner, evt)   
351        try:
352            self.compute_chisqr()
353            self.text1_1.Show()
354            self.tcChi.Show()
355        except:
356            ## error occured on chisqr computation
357            pass
358    def get_range(self):
359        """
360            return the fitting range
361        """
362        return self.qmin_x , self.qmax_x
363       
364    def get_param_list(self):
365        """
366            @return self.param_toFit: list containing  references to TextCtrl
367            checked.Theses TextCtrl will allow reference to parameters to fit.
368            @raise: if return an empty list of parameter fit will nnote work
369            properly so raise ValueError,"missing parameter to fit"
370        """
371        if self.param_toFit !=[]:
372            return self.param_toFit
373        else:
374            raise ValueError,"missing parameter to fit"   
375     
376    def onsetValues(self,chisqr, out,cov):
377        """
378            Build the panel from the fit result
379            @param chisqr:Value of the goodness of fit metric
380            @param out:list of parameter with the best value found during fitting
381            @param cov:Covariance matrix
382       
383        """
384        self.tcChi.SetLabel(format_number(chisqr))
385        params = {}
386        is_modified = False
387        has_error = False
388        self.text2_3.Hide()
389        if self.text_disp_1 !=None:
390            self.text_disp_1.Hide()
391        #set the panel when fit result are float not list
392        if out.__class__==numpy.float64:
393            self.param_toFit[0][2].SetValue(format_number(out))
394            self.param_toFit[0][2].Refresh()
395           
396            self.param_toFit[0][4].Clear()
397            self.param_toFit[0][4].Hide()
398            if cov !=None :
399                self.text2_3.Show(True)
400                if self.text_disp_1 !=None:
401                    self.text_disp_1.Show(True)
402                   
403                self.param_toFit[0][3].Show(True)
404                self.param_toFit[0][4].Clear()
405                self.param_toFit[0][4].SetValue(format_number(cov[0]))
406                self.param_toFit[0][4].Show(True)
407        else:
408            i=0
409            j=0
410            #Set the panel when fit result are list
411            for item in self.param_toFit:
412                ## reset error value to initial state
413                item[4].Clear()
414                item[4].Hide()
415                item[4].Refresh()
416                if( out != None ) and len(out)<=len(self.param_toFit)and i < len(out):
417                    item[2].SetValue(format_number(self.model.getParam(item[1])))
418                    item[2].Refresh()
419                if(cov !=None)and len(cov)<=len(self.param_toFit)and i < len(cov):
420                    self.text2_3.Show(True) 
421                    if self.text_disp_1!=None:
422                        self.text_disp_1.Show(True)
423                    item[3].Show(True)
424                    item[4].Clear()
425                    for j in range(len(out)):
426                        if out[j]==self.model.getParam(item[1]):
427                            break
428                    item[4].SetValue(format_number(cov[j]))
429                    item[4].Refresh()
430                    item[4].Show(True)   
431                i+=1
432       
433        self.sizer3.Layout()
434        self.sizer4.Layout()
435        self.SetScrollbars(20,20,200,100)
436       
437       
438     
439    def onSmear(self, event):
440        """
441            Create a smear object that will change the way residuals
442            are compute when fitting
443        """
444        smear =None
445        msg=""
446        if self.enable_smearer.GetValue():
447            from DataLoader.qsmearing import smear_selection
448            smear = smear_selection( self.data )
449            if hasattr(self.data,"dxl"):
450                msg= ": Resolution smearing parameters"
451            if hasattr(self.data,"dxw"):
452                msg= ": Slit smearing parameters"
453            if smear ==None:
454                wx.PostEvent(self.manager.parent, StatusEvent(status=\
455                            "Data contains no smearing information"))
456            else:
457                wx.PostEvent(self.manager.parent, StatusEvent(status=\
458                            "Data contains smearing information %s"%msg))
459            self.manager.set_smearer(smear, qmin= self.qmin_x, qmax= self.qmax_x)   
460             
461       
462       
463    def compute_chisqr2D(self):
464        """
465            compute chi square given a model and data 2D and set the value
466            to the tcChi txtcrl
467        """
468        from sans.guiframe.utils import check_value
469        flag = check_value( self.qmin, self.qmax)
470       
471        res=[]
472        if flag== True:
473            try:
474                self.qmin_x = float(self.qmin.GetValue())
475                self.qmax_x = float(self.qmax.GetValue())
476                for i in range(len(self.data.x_bins)):
477                    for j in range(len(self.data.y_bins)):
478                        #Check the range containing data between self.qmin_x and self.qmax_x
479                        if math.pow(self.data.x_bins[i],2)+math.pow(self.data.y_bins[j],2)>=math.pow(self.qmin_x,2):
480                            if math.pow(self.data.x_bins[i],2)+math.pow(self.data.y_bins[j],2)<=math.pow(self.qmax_x,2):
481                                chisqrji=(self.data.data[j][i]- self.model.runXY(\
482                                                                                    [self.data.y_bins[j],self.data.x_bins[i]]))\
483                                                                                    /self.data.err_data[j][i]
484                                #Vector containing residuals
485                                res.append( math.pow(chisqrji,2) )
486                # compute sum of residual
487                sum=0
488                for item in res:
489                    if numpy.isfinite(item):
490                        sum +=item
491                self.tcChi.SetLabel(format_number(math.fabs(sum/ len(res))))
492            except:
493                wx.PostEvent(self.parent.GrandParent, StatusEvent(status=\
494                            "Chisqr cannot be compute: %s"% sys.exc_value))
495                return
496   
497       
498    def compute_chisqr(self):
499        """
500            compute chi square given a model and data 1D and set the value
501            to the tcChi txtcrl
502        """
503        from sans.guiframe.utils import check_value
504        flag = check_value( self.qmin, self.qmax)
505       
506        if flag== True:
507            try:
508                if hasattr(self.data,"data"):
509                    self.compute_chisqr2D()
510                    return
511                else:
512                    self.qmin_x = float(self.qmin.GetValue())
513                    self.qmax_x = float(self.qmax.GetValue())
514                    # return residuals within self.qmin_x and self.qmax_x
515                    x,y,dy = [numpy.asarray(v) for v in (self.data.x,self.data.y,self.data.dy)]
516                    if self.qmin_x==None and self.qmax_x==None: 
517                        fx =numpy.asarray([self.model.run(v) for v in x])
518                        temp=(y - fx)/dy
519                        res= temp*temp
520                    else:
521                        idx = (x>= self.qmin_x) & (x <=self.qmax_x)
522                        fx = numpy.asarray([self.model.run(item)for item in x[idx ]])
523                        temp=(y[idx] - fx)/dy[idx]
524                        res= temp*temp
525                    #sum of residuals
526                    sum=0
527                    for item in res:
528                        if numpy.isfinite(item):
529                            sum +=item
530                    self.tcChi.SetLabel(format_number(math.fabs(sum/ len(res))))
531            except:
532                wx.PostEvent(self.parent.GrandParent, StatusEvent(status=\
533                            "Chisqr cannot be compute: %s"% sys.exc_value))
534                return 
535           
536   
537    def select_all_param(self,event): 
538        """
539             set to true or false all checkBox given the main checkbox value cb1
540        """
541        self.param_toFit=[]
542        if  self.parameters !=[]:
543            if  self.cb1.GetValue()==True:
544                for item in self.parameters:
545                    item[0].SetValue(True)
546                    self.param_toFit.append(item )
547                if len(self.fittable_param)>0:
548                    for item in self.fittable_param:
549                        item[0].SetValue(True)
550                        self.param_toFit.append(item )
551            else:
552                for item in self.parameters:
553                    item[0].SetValue(False)
554                for item in self.fittable_param:
555                    item[0].SetValue(False)
556                self.param_toFit=[]
557               
558               
559               
560    def select_param(self,event):
561        """
562            Select TextCtrl  checked for fitting purpose and stores them
563            in  self.param_toFit=[] list
564        """
565        self.param_toFit=[]
566        for item in self.parameters:
567            #Select parameters to fit for list of primary parameters
568            if item[0].GetValue()==True:
569                if not (item in self.param_toFit):
570                    self.param_toFit.append(item ) 
571            else:
572                #remove parameters from the fitting list
573                if item in self.param_toFit:
574                    self.param_toFit.remove(item)
575        #Select parameters to fit for list of fittable parameters with dispersion         
576        for item in self.fittable_param:
577            if item[0].GetValue()==True:
578                if not (item in self.param_toFit):
579                    self.param_toFit.append(item) 
580            else:
581                #remove parameters from the fitting list
582                if item in self.param_toFit:
583                    self.param_toFit.remove(item)           
584        #Set the value of checkbox that selected every checkbox or not           
585        if len(self.parameters)+len(self.fittable_param) ==len(self.param_toFit):
586            self.cb1.SetValue(True)
587        else:
588            self.cb1.SetValue(False)
589   
590   
591    def set_model_description(self,description,sizer):
592        """
593            fill a sizer with description
594            @param description: of type string
595            @param sizer: wx.BoxSizer()
596        """
597   
598        sizer.Clear(True)
599        box_description= wx.StaticBox(self, -1, 'Model Description')
600        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
601               
602        self.description = wx.StaticText( self,-1,str(description) )
603        sizer_selection=wx.BoxSizer(wx.HORIZONTAL)
604       
605       
606        self.description_show = wx.RadioButton(self, -1, 'Show', style=wx.RB_GROUP)
607        self.description_hide = wx.RadioButton(self, -1, 'Hide')
608       
609        self.Bind( wx.EVT_RADIOBUTTON, self._on_display_description,
610                   id=self.description_hide.GetId() )
611       
612        self.Bind( wx.EVT_RADIOBUTTON, self._on_display_description,
613                   id=self.description_show.GetId() )
614       
615        self.model_description = wx.Button(self, -1, "More Details")
616     
617       
618        self.page_info.save_radiobox_state( self.description_hide )
619        self.page_info.save_radiobox_state( self.description_show )
620       
621        sizer_selection.Add( self.description_show )
622        sizer_selection.Add( (20,20)) 
623        sizer_selection.Add( self.description_hide )
624        sizer_selection.Add( (20,20)) 
625        sizer_selection.Add( self.model_description )
626       
627         
628        self.sizer_description=wx.BoxSizer(wx.HORIZONTAL)
629        self.sizer_description.Add( self.description, 1, wx.EXPAND | wx.ALL, 10 )
630       
631        boxsizer1.Add( sizer_selection) 
632        boxsizer1.Add( (20,20)) 
633        boxsizer1.Add( self.sizer_description) 
634   
635
636        sizer.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10)
637        sizer.Layout()
638   
639   
640       
641       
642    def set_model_param_sizer(self, model, engine_type="park"):
643        """
644            Build the panel from the model content
645            @param model: the model selected in combo box for fitting purpose
646        """
647        self.sizer3.Clear(True)
648        self.parameters = []
649        self.param_toFit=[]
650        self.fittable_param=[]
651        self.fixed_param=[]
652       
653        if model ==None:
654            self.sizer3.Layout()
655            self.SetScrollbars(20,20,200,100)
656            return
657        box_description= wx.StaticBox(self, -1,str("Model Parameters"))
658        boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)
659        sizer = wx.GridBagSizer(5,5)
660        ## save the current model
661        self.model = model
662           
663        keys = self.model.getParamList()
664        #list of dispersion paramaters
665        self.disp_list=self.model.getDispParamList()
666       
667        keys.sort()
668   
669        iy = 1
670        ix = 0
671        self.cb1 = wx.CheckBox(self, -1,"Select all", (10, 10))
672        wx.EVT_CHECKBOX(self, self.cb1.GetId(), self.select_all_param)
673        self.cb1.SetValue(False)
674       
675        sizer.Add(self.cb1,(iy, ix),(1,1),\
676                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
677        ix +=1
678        self.text2_2 = wx.StaticText(self, -1, 'Values')
679        sizer.Add(self.text2_2,(iy, ix),(1,1),\
680                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
681        ix +=2 
682        self.text2_3 = wx.StaticText(self, -1, 'Errors')
683        sizer.Add(self.text2_3,(iy, ix),(1,1),\
684                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
685        self.text2_3.Hide()
686        ix +=1 
687        self.text2_min = wx.StaticText(self, -1, 'Min')
688        sizer.Add(self.text2_min,(iy, ix),(1,1),\
689                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
690        self.text2_min.Hide()
691        ix +=1 
692        self.text2_max = wx.StaticText(self, -1, 'Max')
693        sizer.Add(self.text2_max,(iy, ix),(1,1),\
694                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
695        self.text2_max.Hide()
696        ix += 1
697        self.text2_4 = wx.StaticText(self, -1, 'Units')
698        sizer.Add(self.text2_4,(iy, ix),(1,1),\
699                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
700        self.text2_4.Hide()
701        if  engine_type == "park":
702            self.text2_max.Show(True)
703            self.text2_min.Show(True)
704
705        for item in keys:
706            if not item in self.disp_list:
707                iy += 1
708                ix = 0
709                ## add parameters name with checkbox for selecting to fit
710                cb = wx.CheckBox(self, -1, item )
711                cb.SetValue(False)
712                wx.EVT_CHECKBOX(self, cb.GetId(), self.select_param)
713                sizer.Add( cb,( iy, ix),(1,1),
714                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
715                ## add parameter value
716                ix += 1
717                value= self.model.getParam(item)
718                ctl1 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20),
719                                    style=wx.TE_PROCESS_ENTER)
720               
721                ctl1.SetValue(str (format_number(value)))
722                ctl1.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)
723                ctl1.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter)
724                sizer.Add(ctl1, (iy,ix),(1,1), wx.EXPAND)
725                ## text to show error sign
726                ix += 1
727                text2=wx.StaticText(self, -1, '+/-')
728                sizer.Add(text2,(iy, ix),(1,1),\
729                                wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
730                text2.Hide() 
731                ## txtcrtl to add error from fit
732                ix += 1
733                ctl2 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH,20), style=wx.TE_PROCESS_ENTER)
734                sizer.Add(ctl2, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
735                ctl2.Hide()
736               
737                ix += 1
738                ctl3 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER)
739                ctl3.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)
740                ctl3.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter)
741                sizer.Add(ctl3, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
742                ctl3.Hide()
743               
744                ix += 1
745                ctl4 = wx.TextCtrl(self, -1, size=(_BOX_WIDTH/2,20), style=wx.TE_PROCESS_ENTER)
746                ctl4.Bind(wx.EVT_KILL_FOCUS, self._onparamEnter)
747                ctl4.Bind(wx.EVT_TEXT_ENTER,self._onparamEnter)
748                sizer.Add(ctl4, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
749                ctl4.Hide()
750                if  engine_type == "park":
751                    ctl3.Show(True)
752                    ctl4.Show(True)
753                   
754                ix +=1
755                # Units
756                try:
757                    units = wx.StaticText(self, -1, self.model.details[item][0], style=wx.ALIGN_LEFT)
758                except:
759                    units = wx.StaticText(self, -1, "", style=wx.ALIGN_LEFT)
760                sizer.Add(units, (iy,ix),(1,1),  wx.EXPAND|wx.ADJUST_MINSIZE, 0)
761               
762                ##[cb state, name, value, "+/-", error of fit, min, max , units]
763                self.parameters.append([cb,item, ctl1,
764                                        text2,ctl2, ctl3, ctl4,None])
765               
766        iy+=1
767        sizer.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
768       
769        #Display units text on panel
770        for item in keys:   
771            if self.model.details[item][0]!='':
772                self.text2_4.Show()
773                break
774            else:
775                self.text2_4.Hide()
776   
777        boxsizer1.Add(sizer)
778       
779        self.sizer3.Add(boxsizer1,0, wx.EXPAND | wx.ALL, 10)
780        self.sizer3.Layout()
781        self.SetScrollbars(20,20,200,100)
782       
783   
784           
785       
786class HelpWindow(wx.Frame):
787    def __init__(self, parent, id, title):
788        wx.Frame.__init__(self, parent, id, title, size=(570, 400))
789       
790        from sans.models.CylinderModel import CylinderModel
791        model = CylinderModel()
792        #from sans.models.LineModel import LineModel
793        #model = LineModel()
794        from danse.common.plottools.plottables import Data1D
795        data= Data1D(x=[1,2], y=[3,4], dy=[0.1, 0,1])
796   
797        from pageInfo import PageInfo
798        myinfo = PageInfo(self,  model, data=data )
799       
800        ## add data
801       
802        from models import ModelList
803        mylist= ModelList()
804
805        from sans.models.SphereModel import SphereModel
806        from sans.models.SquareWellStructure import SquareWellStructure
807        from sans.models.DebyeModel import DebyeModel
808        from sans.models.LineModel import LineModel
809        name= "shapes"
810        list1= [SphereModel]
811        mylist.set_list( name, list1)
812       
813        name= "Shape-independent"
814        list1= [DebyeModel]
815        mylist.set_list( name, list1)
816       
817        name= "Structure Factors"
818        list1= [SquareWellStructure]
819        mylist.set_list( name, list1)
820       
821        name= "Added models"
822        list1= [LineModel]
823        mylist.set_list( name, list1)
824       
825        myinfo.model_list_box = mylist.get_list()
826       
827        self.page = FitPage(self, myinfo) 
828       
829       
830       
831        self.Centre()
832        self.Show(True)
833
834
835   
836if __name__=="__main__":
837    app = wx.App()
838    HelpWindow(None, -1, 'HelpWindow')
839    app.MainLoop()
840               
Note: See TracBrowser for help on using the repository browser.