source: sasview/guitools/fitDialog.py @ 1fdb81d

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

modified plotpanel and fitdialog

  • Property mode set to 100644
File size: 8.6 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
9class LinearFit(wx.Dialog):
10    #def __init__(self, parent, id, title):
11    def __init__(self, parent, plottable, push_data,transform, id, title):
12        wx.Dialog.__init__(self, parent, id, title, size=(550, 300))
13        """
14            for the fit window
15        """
16        self.parent = parent
17        self.transform = transform
18        #dialog panel self call function to plot the fitting function
19        self.push_data = push_data
20        #dialog self plottable
21        self.plottable = plottable
22       
23        #Dialog interface
24        panel = wx.Panel(self, -1, style=wx.SIMPLE_BORDER)   
25        vbox  = wx.BoxSizer(wx.VERTICAL)
26        sizer = wx.GridBagSizer(5,0)
27        vbox.Add(panel, 1, wx.EXPAND | wx.ALL)
28 
29        self.tcA = wx.TextCtrl(panel, -1,size=(120,20),style=wx.SIMPLE_BORDER)
30        self.tcErrA = wx.TextCtrl(panel, -1,size=(120,20),style=wx.SIMPLE_BORDER)
31        self.tcB = wx.TextCtrl(panel, -1,size=(120,20),style=wx.SIMPLE_BORDER)
32        self.tcErrB = wx.TextCtrl(panel, -1,size=(120,20),style=wx.SIMPLE_BORDER)
33        self.tcChi = wx.TextCtrl(panel, -1,size=(120,20),style=wx.SIMPLE_BORDER)
34        self.tcXmin = wx.TextCtrl(panel,-1,size=(120,20),style=wx.SIMPLE_BORDER)
35        self.tcXmax = wx.TextCtrl(panel,-1,size=(120,20),style=wx.SIMPLE_BORDER)
36        self.btFit =wx.Button(panel,-1,'Fit' )
37        btClose =wx.Button(panel, wx.ID_CANCEL,'Close' )
38       
39        ix = 1
40        iy = 1
41       
42        sizer.Add(wx.StaticText(panel, -1, 'y = Ax +B'),(iy, ix))
43        ix = 1
44        iy += 2
45       
46        sizer.Add(wx.StaticText(panel, -1, 'Param A'),(iy, ix))
47        ix += 1
48        sizer.Add(self.tcA, (iy, ix))
49        ix += 1
50        sizer.Add(wx.StaticText(panel, -1, '+/-'),(iy, ix))
51        ix += 1
52        sizer.Add(self.tcErrA, (iy, ix))
53        iy += 1
54        ix = 1
55        sizer.Add(wx.StaticText(panel, -1, 'Param B'),(iy, ix))
56        ix += 1
57        sizer.Add(self.tcB, (iy, ix))
58        ix += 1
59        sizer.Add(wx.StaticText(panel, -1, '+/-'),(iy, ix))
60        ix += 1
61        sizer.Add(self.tcErrB, (iy, ix))
62        iy += 1
63        ix = 1
64        sizer.Add(wx.StaticText(panel, -1, 'Chi ^{2}'),(iy, ix))
65        ix += 1
66        sizer.Add(self.tcChi, (iy, ix))
67        iy += 1
68        ix = 1
69        sizer.Add(wx.StaticText(panel, -1, 'Xmin'),(iy, ix))
70        ix += 2
71        sizer.Add(wx.StaticText(panel, -1, 'Xmax'),(iy, ix))
72        iy += 1
73        ix = 1
74        sizer.Add(self.tcXmin, (iy, ix))
75        ix += 2
76        sizer.Add(self.tcXmax, (iy, ix))
77        iy += 1
78        ix = 3
79        sizer.Add(self.btFit, (iy, ix))
80        self.btFit.Bind(wx.EVT_BUTTON, self._onFit)
81        iy +=1
82        ix = 3
83        sizer.Add(btClose, (iy, ix))
84       
85        panel.SetSizer(sizer)
86        self.SetSizer(vbox)
87        self.Centre()
88        # Receives the type of model for the fitting
89        from LineModel import LineModel
90        self.model  = LineModel()
91         
92         
93        #Display the fittings values
94        self.default_A = self.model.getParam('A') 
95        self.default_B = self.model.getParam('B') 
96        self.cstA = fittings.Parameter(self.model, 'A', self.default_A)
97        self.cstB  = fittings.Parameter(self.model, 'B', self.default_B)
98       
99        # Set default value of parameter in fit dialog
100        self.tcA.SetLabel(str(self.default_A))
101        self.tcB.SetLabel(str(self.default_B))
102        self.tcErrA.SetLabel(str(0.0))
103        self.tcErrB.SetLabel(str(0.0))
104        self.tcChi.SetLabel(str(0.0))
105        self.tcXmin.SetLabel(str(0.0))
106        self.tcXmax.SetLabel(str(0.0))
107       
108        # new data for the fit
109        self.file_data1 = Theory1D(x=[], y=[], dy=None)
110        self.file_data1.name = "Fit"
111       
112    def _onFit(self ,event):
113        """
114            Performs the fit. Receive an event when clicking on the button Fit.Computes chisqr ,
115            A and B parameters of the best linear fit y=Ax +B
116            Push a plottable to
117        """
118       
119        tempx=[]
120        tempy=[]
121        tempdy = []
122       
123        #Check if the field of Fit Dialog contain values and use the x max and min of the user
124        xmin = self._checkVal(self.tcXmin.GetValue())
125        xmax = self._checkVal(self.tcXmax.GetValue())
126       
127        #store the values of View in x,y, dx,dy
128        x,y,dx,dy=self.plottable.returnValuesOfView()
129        # Receive transformations of x and y
130        self.xtrans,self.ytrans= self.transform()
131       
132                       
133        if (xmin ==None)and (xmax == None):
134            #Display the min and the max of x on fit dialog fields
135            self.tcXmin.SetValue(str(min(x)))
136            self.tcXmax.SetValue(str(max(x)))
137     
138       
139        # Store the transformed values of view x, y,dy in variables  before the fit
140        if  self.ytrans == "Log(y)":
141            for y_i in y:
142                tempy.append(math.log(y_i)) 
143                dy = 1/y_i
144                if dy >= y_i:
145                    dy = 0.9*y_i
146                tempdy.append(dy)
147        else:
148            tempy = y
149        if  self.xtrans == "Log(x)":
150            for x_i in x:
151                tempx.append(math.log(x_i)) 
152        else:
153            tempx = x
154           
155        #Find the fitting parameters
156        if (xmin !=None and xmin >= min(tempx) ) and (xmax != None and xmax <= max(tempx)):   
157            chisqr, out, cov = fittings.sansfit(self.model, 
158                        [self.cstA, self.cstB],tempx, tempy,tempdy,xmin,xmax)
159        else:
160            chisqr, out, cov = fittings.sansfit(self.model, 
161                        [self.cstA, self.cstB],tempx, tempy,tempdy,min(tempx),max(tempx))
162       
163        #Check that cov and out are iterable before displaying them
164        if cov ==None:
165            errA =0.0
166            errB =0.0
167        else:
168            errA= math.sqrt(cov[0][0])
169            errB= math.sqrt(cov[1][1])
170        if out==None:
171            cstA=0.0
172            cstB=0.0
173        else:
174            cstA=out[0]
175            cstB=out[1]
176        # Reset model with the right values of A and B
177        self.model.setParam('A', float(cstA))
178        self.model.setParam('B', float(cstB))
179        tempy = []
180        # Check if View contains a x array .we online fit when x exits
181        # makes transformation for y as a line to fit
182        if x != []:
183            for j in range(len(x)): 
184                    if (xmin !=None)and (xmax != None):
185                        if (x[j] > xmin and x[j] < xmax):
186                            y_model = self.model.run(x[j])
187                    else:
188                        # x has a default value in case the user doesn't load data
189                        if self.xtrans == "Log(x)":
190                            y_model = self.model.run(math.log(x[j]))
191                        else:
192                            y_model = self.model.run(x[j])
193                   
194                    if self.ytrans == "Log(y)":
195                        tempy.append(math.exp(y_model))
196                    else:
197                        tempy.append(y_model)
198                       
199            # Create new data plottable with result
200            self.file_data1.x =x
201            self.file_data1.y =[] 
202            self.file_data1.y =tempy     
203            self.file_data1.dx=None
204            self.file_data1.dy=None
205           
206            #Load the view with the new values
207            self.file_data1.reset_view()
208           
209            #Send the data to display to the PlotPanel
210            self.push_data(self.file_data1)
211           
212            # Display the fitting value on the Fit Dialog
213            self._onsetValues(cstA, cstB, errA,errB,chisqr)
214   
215    def _onsetValues(self,cstA,cstB,errA,errB,Chi):
216         """
217              Display  the value on fit Dialog
218         """
219         self.tcA.SetValue(str(cstA))
220         self.tcB.SetValue(str(cstB))
221         self.tcErrA.SetValue(str(errA))
222         self.tcErrB.SetValue(str(errB))
223         self.tcChi.SetValue(str(Chi))
224         
225    def _returnPlottable(self):
226        return self.file_data1
227   
228    def _checkVal(self,value):
229        """
230                Ensure that field parameter contains a value
231                before sending to fit
232        """
233        try:
234            param = float(value)
235        except:
236            param = None
237        return param
238if __name__ == "__main__": 
239    app = wx.App()
240    dialog=LinearFit(None, -1, 'Fitting')
241    dialog.ShowModal()
242    app.MainLoop()
243
244
Note: See TracBrowser for help on using the repository browser.