source: sasview/guitools/fitDialog.py @ ddff053

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

making change on fitdialog ..still some bugs

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