source: sasview/guitools/fitDialog.py @ 150c04a

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 150c04a was 416223d, checked in by Gervaise Alina <gervyh@…>, 16 years ago

more change on fitdialog

  • Property mode set to 100644
File size: 14.7 KB
RevLine 
[6cfe703]1#!/usr/bin/python
2
3# fitDialog.py
4
5import wx
[e40b651]6from PlotPanel import PlotPanel
7from plottables import Theory1D
8import math,pylab,fittings
[831149e]9import transform
10
11
[6cfe703]12class LinearFit(wx.Dialog):
[e40b651]13    #def __init__(self, parent, id, title):
[f52bea1]14    def __init__(self, parent, plottable, push_data,transform, id, title):
[90640f2]15        wx.Dialog.__init__(self, parent, id, title, size=(450, 400))
[6cfe703]16        """
17            for the fit window
18        """
19        self.parent = parent
[f52bea1]20        self.transform = transform
[e40b651]21        #dialog panel self call function to plot the fitting function
22        self.push_data = push_data
23        #dialog self plottable
24        self.plottable = plottable
[ddff053]25        # Receive transformations of x and y
26        self.xtrans,self.ytrans= self.transform()
[e40b651]27        #Dialog interface
[6cfe703]28        panel = wx.Panel(self, -1, style=wx.SIMPLE_BORDER)   
29        vbox  = wx.BoxSizer(wx.VERTICAL)
[106ef4d]30        sizer = wx.GridBagSizer(5,5)
31       
[6cfe703]32        vbox.Add(panel, 1, wx.EXPAND | wx.ALL)
33 
[f63f5ff]34        self.tcA = wx.TextCtrl(panel, -1,size=(120,20),style=wx.SIMPLE_BORDER)
35        self.tcErrA = wx.TextCtrl(panel, -1,size=(120,20),style=wx.SIMPLE_BORDER)
36        self.tcB = wx.TextCtrl(panel, -1,size=(120,20),style=wx.SIMPLE_BORDER)
37        self.tcErrB = wx.TextCtrl(panel, -1,size=(120,20),style=wx.SIMPLE_BORDER)
38        self.tcChi = wx.TextCtrl(panel, -1,size=(120,20),style=wx.SIMPLE_BORDER)
[831149e]39        self.FXmin = wx.TextCtrl(panel,-1,size=(120,20),style=wx.SIMPLE_BORDER)
40        self.FXmax = wx.TextCtrl(panel,-1,size=(120,20),style=wx.SIMPLE_BORDER)
[ddff053]41        self.FXminX = wx.TextCtrl(panel,-1,size=(120,20),style=wx.SIMPLE_BORDER)
42        self.FXmaxX = wx.TextCtrl(panel,-1,size=(120,20),style=wx.SIMPLE_BORDER)
[831149e]43        self.PXmin = wx.TextCtrl(panel,-1,size=(120,20),style=wx.SIMPLE_BORDER)
44        self.PXmax = wx.TextCtrl(panel,-1,size=(120,20),style=wx.SIMPLE_BORDER)
[106ef4d]45        self.btFit =wx.Button(panel,-1,'Fit',size=(120, 30))
46        self.btClose =wx.Button(panel, wx.ID_CANCEL,'Close',size=(90, 30) )
47        self.static_line_1 = wx.StaticLine(panel, -1)
[8e44d51]48       
[106ef4d]49        ix = 0
[6cfe703]50        iy = 1
[106ef4d]51        sizer.Add(wx.StaticText(panel, -1, 'y = Ax +B'),(iy, ix),(1,1),\
52                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
53        iy+=1
54        sizer.Add(wx.StaticText(panel, -1, 'Param A'),(iy, ix),\
55                 (1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
[6cfe703]56        ix += 1
[106ef4d]57        sizer.Add(self.tcA,(iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[6cfe703]58        ix += 1
[106ef4d]59        sizer.Add(wx.StaticText(panel, -1, '+/-'),(iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[6cfe703]60        ix += 1
[106ef4d]61        sizer.Add(self.tcErrA, (iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[6cfe703]62        iy += 1
[106ef4d]63        ix = 0
64        sizer.Add(wx.StaticText(panel, -1, 'Param B'),(iy, ix),(1,1),\
65                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
[6cfe703]66        ix += 1
[106ef4d]67        sizer.Add(self.tcB, (iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[6cfe703]68        ix += 1
[106ef4d]69        sizer.Add(wx.StaticText(panel, -1, '+/-'),(iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[6cfe703]70        ix += 1
[106ef4d]71        sizer.Add(self.tcErrB, (iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[6cfe703]72        iy += 1
[106ef4d]73        ix = 0
74        sizer.Add(wx.StaticText(panel, -1, 'Chi ^{2}'),(iy, ix),(1,1),\
75                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
[6cfe703]76        ix += 1
[106ef4d]77        sizer.Add(self.tcChi, (iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[6cfe703]78        iy += 1
79        ix = 1
[106ef4d]80        sizer.Add(wx.StaticText(panel, -1, 'Xmin'),(iy, ix),(1,1),\
81                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[6cfe703]82        ix += 2
[106ef4d]83        sizer.Add(wx.StaticText(panel, -1, 'Xmax'),(iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[6cfe703]84        iy += 1
[831149e]85        ix = 0
86        sizer.Add(wx.StaticText(panel, -1, 'Plotted Range'),(iy, ix),(1,1),\
87                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
88        ix +=1
89        sizer.Add(self.PXmin, (iy, ix),(1,1),\
90                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
91        ix += 2
92        sizer.Add(self.PXmax, (iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
93        iy += 1
[ddff053]94        ix = 1
95        sizer.Add(wx.StaticText(panel, -1,"x transofrmation is: "+self.xtrans ),(iy, ix),(1,1),\
96                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
97        iy += 1
[831149e]98        ix = 0
99        sizer.Add(wx.StaticText(panel, -1, 'Fit Range'),(iy, ix),(1,1),\
100                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
101        ix += 1
102        sizer.Add(self.FXmin, (iy, ix),(1,1),\
[106ef4d]103                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[6cfe703]104        ix += 2
[831149e]105        sizer.Add(self.FXmax, (iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[90640f2]106     
[ddff053]107        iy += 1
108        ix = 0
109        sizer.Add(wx.StaticText(panel, -1, 'Fit Range of x'),(iy, ix),(1,1),\
110                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
111        ix += 1
112        sizer.Add(self.FXminX, (iy, ix),(1,1),\
113                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
114        ix += 2
115        sizer.Add(self.FXmaxX, (iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
[6cfe703]116        iy += 1
[106ef4d]117        ix = 1
118       
119        sizer.Add(self.btFit, (iy, ix),(1,1), wx.LEFT|wx.ADJUST_MINSIZE, 0)
[e40b651]120        self.btFit.Bind(wx.EVT_BUTTON, self._onFit)
[106ef4d]121        ix += 2
122        sizer.Add(self.btClose, (iy, ix),(1,1),\
123                  wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
124       
[6cfe703]125        panel.SetSizer(sizer)
126        self.SetSizer(vbox)
127        self.Centre()
[8e44d51]128       
[e40b651]129        # Receives the type of model for the fitting
130        from LineModel import LineModel
131        self.model  = LineModel()
[1fdb81d]132         
133        #Display the fittings values
134        self.default_A = self.model.getParam('A') 
135        self.default_B = self.model.getParam('B') 
136        self.cstA = fittings.Parameter(self.model, 'A', self.default_A)
137        self.cstB  = fittings.Parameter(self.model, 'B', self.default_B)
138       
139        # Set default value of parameter in fit dialog
140        self.tcA.SetLabel(str(self.default_A))
141        self.tcB.SetLabel(str(self.default_B))
142        self.tcErrA.SetLabel(str(0.0))
143        self.tcErrB.SetLabel(str(0.0))
144        self.tcChi.SetLabel(str(0.0))
[90640f2]145       
[831149e]146        if self.plottable.x !=[]:
147            self.mini =min(self.plottable.x)
148            self.maxi =max(self.plottable.x)
[90640f2]149           
[831149e]150            self.FXmin.SetLabel(str(self.mini))
151            self.FXmax.SetLabel(str(self.maxi))
[ddff053]152            self.FXmin.Disable()
153            self.FXmax.Disable()
[90640f2]154           
[831149e]155            self.PXmin.SetValue(str(self.mini))
156            self.PXmax.SetValue(str(self.maxi))
157            self.PXmin.Disable()
158            self.PXmax.Disable()
[90640f2]159           
160            self.FXminX.SetLabel(str(self.mini))
161            self.FXmaxX.SetLabel(str(self.maxi))
162           
163     
[6cfe703]164    def _onFit(self ,event):
[f52bea1]165        """
166            Performs the fit. Receive an event when clicking on the button Fit.Computes chisqr ,
167            A and B parameters of the best linear fit y=Ax +B
168            Push a plottable to
169        """
170        tempx=[]
171        tempy=[]
[7a03e65]172        tempdy = []
[ddff053]173       
[5789654]174        #store the values of View in x,y, dx,dy
175        x,y,dx,dy=self.plottable.returnValuesOfView()
[1fdb81d]176       
[106ef4d]177        # Check if View contains a x array .we online fit when x exits
178        # makes transformation for y as a line to fit
[831149e]179        if x != []: 
[ddff053]180           
181               
[90640f2]182            if(self.checkFitValues(self.FXminX) == True):
[f193585]183                #Check if the field of Fit Dialog contain values and use the x max and min of the user
[ddff053]184                xmin,xmax = self._checkVal(self.FXminX.GetValue(),self.FXmaxX.GetValue())
185               
[f193585]186                xminView=self.floatTransform(xmin)
187                xmaxView=self.floatTransform(xmax)
[416223d]188                if (self.xtrans=="log10(x)"):
189                    self.FXmin.SetValue(str(math.log10(xminView)))
190                    self.FXmax.SetValue(str(math.log10(xmaxView)))
191                else:
192                    self.FXmin.SetValue(str(xminView))
193                    self.FXmax.SetValue(str(xmaxView))
[ddff053]194                self.FXmin.Disable()
195                self.FXmax.Disable()
[f193585]196                # Store the transformed values of view x, y,dy in variables  before the fit
197                if  self.ytrans.lower() == "log10(y)":
198                    if (self.xtrans.lower() == "log10(x)"):
199                        for i in range(len(x)):
[34ae302]200                            if x[i]>= math.log10(xmin):
[f193585]201                                tempy.append(math.log10(y[i])) 
202                                tempdy.append(transform.errToLogX(y[i],0,dy[i],0))
203                    else:
[34ae302]204                        for i in range(len(y)):
205                            tempy.append(math.log10(y[i])) 
[f193585]206                            tempdy.append(transform.errToLogX(y[i],0,dy[i],0))
207                else:
208                    tempy = y
209                    tempdy = dy
210               
211                if (self.xtrans.lower() == "log10(x)"):
212                    for x_i in x:
[34ae302]213                        if x_i >= math.log10(xmin):
[f193585]214                            tempx.append(math.log10(x_i)) 
215                else:
216                    tempx = x
217                       
218                #for y_i in y:
219                #    dy = math.sqrt(math.fabs(y_i))
220                #    if dy >= y_i:
221                #        dy = 0.9*y_i
222                #    tempdy.append(dy)
223                       
224                #Find the fitting parameters
[ddff053]225               
[34ae302]226                if (self.xtrans.lower() == "log10(x)"):
227                    chisqr, out, cov = fittings.sansfit(self.model, [self.cstA, self.cstB],
228                    tempx, tempy,tempdy,math.log10(xmin),math.log10(xmax))
229                else:
230                    chisqr, out, cov = fittings.sansfit(self.model, 
[f193585]231                                [self.cstA, self.cstB],tempx, tempy,tempdy,xminView,xmaxView)
232                print "this out",out
233                #Check that cov and out are iterable before displaying them
234                if cov ==None:
235                    errA =0.0
236                    errB =0.0
237                else:
238                    errA= math.sqrt(cov[0][0])
239                    errB= math.sqrt(cov[1][1])
240                if out==None:
241                    cstA=0.0
242                    cstB=0.0
243                else:
244                    cstA=out[0]
245                    cstB=out[1]
246                # Reset model with the right values of A and B
247                self.model.setParam('A', float(cstA))
248                self.model.setParam('B', float(cstB))
[3aa7074]249               
[f193585]250                tempx = []
251                tempy = []
252                y_model = 0.0
253                # load tempy with the minimum transformation
254               
255                if self.xtrans == "log10(x)":
256                    y_model = self.model.run(math.log10(xmin))
257                    tempx.append(xmin)
258                else:
259                    y_model = self.model.run(xminView)
260                    tempx.append(xminView)
261                   
262                if self.ytrans == "log10(y)":
263                    tempy.append(math.pow(10,y_model))
264                    print "tempy",tempy
265                else:
266                    tempy.append(y_model)
267                   
268                # load tempy with the maximum transformation
269                if self.xtrans == "log10(x)":
270                    y_model = self.model.run(math.log10(xmax))
271                    tempx.append(xmax)
272                else:
273                    y_model = self.model.run(xmaxView)
274                    tempx.append(xmaxView)
275                   
276                if self.ytrans == "log10(y)":
277                    tempy.append(math.pow(10,y_model))
278                else: 
279                    tempy.append(y_model)
[ddff053]280               
281                self.push_data(tempx,tempy,xminView,xmaxView,xmin,xmax)
[f193585]282               
283                # Display the fitting value on the Fit Dialog
284                self._onsetValues(cstA, cstB, errA,errB,chisqr)
[7a03e65]285           
[6cfe703]286    def _onsetValues(self,cstA,cstB,errA,errB,Chi):
[f52bea1]287         """
288              Display  the value on fit Dialog
289         """
290         self.tcA.SetValue(str(cstA))
291         self.tcB.SetValue(str(cstB))
292         self.tcErrA.SetValue(str(errA))
293         self.tcErrB.SetValue(str(errB))
294         self.tcChi.SetValue(str(Chi))
[e40b651]295         
296    def _returnPlottable(self):
297        return self.file_data1
298   
[831149e]299    def _checkVal(self,usermin, usermax):
[6cfe703]300        """
[831149e]301                Ensure that fields parameter contains a min and a max value
302                within x min and x max range
[6cfe703]303        """
[831149e]304        if float(usermin) < float(usermax):
305            if float(usermin) >= float(self.mini) and float(usermin) < float(self.maxi):
[ddff053]306                self.FXminX.SetValue(str(usermin))
[831149e]307            else:
[ddff053]308                self.FXminX.SetValue(str(self.mini))
[831149e]309               
310            if float(usermax) > float(self.mini) and float(usermax) <= float(self.maxi):
[ddff053]311                self.FXmaxX.SetLabel(str(usermax))
[831149e]312            else:
[ddff053]313                self.FXmaxX.SetLabel(str(self.maxi))
[831149e]314               
[ddff053]315            mini =float(self.FXminX.GetValue())
316            maxi =float(self.FXmaxX.GetValue())
[831149e]317           
318            return mini, maxi
319    def floatTransform(self,x):
320        """
321             transform a float.It is use to determine the x.View min and x.View max for values
322             not in x
323        """
324        if ( self.xtrans=="x" ):
325            return transform.toX(x)
326       
[f193585]327        if ( self.xtrans=="x^(2)" ): 
[831149e]328            return transform.toX2(x)
329       
330        if (self.xtrans=="log10(x)" ):
331            if x >0:
[34ae302]332                return x
[831149e]333            else:
334                raise ValueError,"cannot compute log of a negative number"
[f193585]335           
336    def checkFitValues(self,item):
337        """
338            Check the validity of input values
339        """
340        flag = True
341        value = item.GetValue()
342        # Check for possible values entered
343        if (self.xtrans=="log10(x)"):
344            if (float(value) > 0):
345                item.SetBackgroundColour(wx.WHITE)
346                item.Refresh()
347            else:
348                flag = False
349                item.SetBackgroundColour("pink")
350                item.Refresh()
351     
352        return flag
[831149e]353       
[ddff053]354    def setFitRange(self,xmin,xmax,Reelxmin,Reelxmax):
[90640f2]355        if (self.xtrans=="log10(x)"):
356            self.FXmin.SetValue(str(math.log10(xmin)))
357            self.FXmax.SetValue(str(math.log10(xmax)))
358        else:
359            self.FXmin.SetValue(str(xmin))
360            self.FXmax.SetValue(str(xmax))
[ddff053]361        self.FXminX.SetValue(str(Reelxmin))
362        self.FXmaxX.SetValue(str(Reelxmax))
363       
[106ef4d]364   
[6cfe703]365if __name__ == "__main__": 
366    app = wx.App()
367    dialog=LinearFit(None, -1, 'Fitting')
368    dialog.ShowModal()
369    app.MainLoop()
370
371
Note: See TracBrowser for help on using the repository browser.