source: sasview/src/danse/common/plottools/fitDialog.py @ 5777106

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 5777106 was 5777106, checked in by Mathieu Doucet <doucetm@…>, 11 years ago

Moving things around. Will definitely not build.

  • Property mode set to 100644
File size: 28.3 KB
Line 
1import wx
2from plottables import Theory1D
3import math
4import numpy
5import fittings
6import transform
7import sys
8
9#Linear fit panel size
10if sys.platform.count("win32") > 0:
11    FONT_VARIANT = 0
12    PNL_WIDTH = 450
13    PNL_HEIGHT = 500
14else:
15    FONT_VARIANT = 1
16    PNL_WIDTH = 500
17    PNL_HEIGHT = 500
18RG_ON = True   
19   
20def format_number(value, high=False):
21    """
22    Return a float in a standardized, human-readable formatted string
23    """
24    try:
25        value = float(value)
26    except:
27        output = "NaN"
28        return output.lstrip().rstrip()
29   
30    if high:
31        output = "%-6.4g" % value
32       
33    else:
34        output = "%-5.3g" % value
35    return output.lstrip().rstrip()
36
37
38class LinearFit(wx.Dialog):
39    def __init__(self, parent, plottable, push_data, transform, title):
40        """
41        Dialog window pops- up when select Linear fit on Context menu
42        Displays fitting parameters
43        """
44        wx.Dialog.__init__(self, parent, title=title, 
45                           size=(PNL_WIDTH, 350))
46        self.parent = parent
47        self.transform = transform
48        #Font
49        self.SetWindowVariant(variant=FONT_VARIANT)
50        # Registered owner for close event
51        self._registered_close = None
52       
53        #dialog panel self call function to plot the fitting function
54        self.push_data = push_data
55        #dialog self plottable
56        self.plottable = plottable
57        self.rg_on = False
58        # Receive transformations of x and y
59        self.xLabel, self.yLabel, self.Avalue, self.Bvalue,\
60               self.ErrAvalue, self.ErrBvalue, self.Chivalue = self.transform()
61       
62        #Dialog interface
63        vbox  = wx.BoxSizer(wx.VERTICAL)
64        sizer = wx.GridBagSizer(5, 5)
65        _BOX_WIDTH = 100
66 
67        self.tcA      = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
68        self.tcA.SetToolTipString("Fit value for the slope parameter.")
69        self.tcErrA   = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
70        self.tcErrA.SetToolTipString("Error on the slope parameter.")
71        self.tcB      = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
72        self.tcA.SetToolTipString("Fit value for the constant parameter.")
73        self.tcErrB   = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
74        self.tcErrB.SetToolTipString("Error on the constant parameter.")
75        self.tcChi    = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
76        self.tcChi.SetToolTipString("Chi^2 over degrees of freedom.")
77        self.xminFit  = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
78        msg = "Enter the minimum value on "
79        msg += "the x-axis to be included in the fit."
80        self.xminFit.SetToolTipString(msg)
81        self.xmaxFit  = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
82        msg = "Enter the maximum value on "
83        msg += " the x-axis to be included in the fit."
84        self.xmaxFit.SetToolTipString(msg)
85        self.initXmin = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
86        msg = "Minimum value on the x-axis for the plotted data."
87        self.initXmin.SetToolTipString(msg)
88        self.initXmax = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20))
89        msg = "Maximum value on the x-axis for the plotted data."
90        self.initXmax.SetToolTipString(msg)
91
92        # Make the info box not editable
93        #_BACKGROUND_COLOR = '#ffdf85'
94        _BACKGROUND_COLOR = self.GetBackgroundColour()
95        self.initXmin.SetEditable(False)
96        self.initXmin.SetBackgroundColour(_BACKGROUND_COLOR)
97        self.initXmax.SetEditable(False)
98        self.initXmax.SetBackgroundColour(_BACKGROUND_COLOR)
99       
100        # Buttons on the bottom
101        self.bg_on = False
102        self.static_line_1 = wx.StaticLine(self, -1)
103        self.btFit = wx.Button(self, -1, 'Fit')
104        self.btFit.Bind(wx.EVT_BUTTON, self._onFit)
105        self.btFit.SetToolTipString("Perform fit.")
106        self.btClose =wx.Button(self, wx.ID_CANCEL, 'Close')
107        self.btClose.Bind(wx.EVT_BUTTON, self._on_close)
108        if RG_ON:
109            if (self.yLabel == "ln(y)" or self.yLabel == "ln(y*x)") and \
110                    (self.xLabel == "x^(2)"):
111                self.rg_on = True
112            if (self.xLabel == "x^(4)") and (self.yLabel == "y*x^(4)"):
113                self.bg_on = True
114        # Intro
115        explanation = "Perform fit for y(x) = ax + b"
116        if self.bg_on:
117            param_a = 'Background (= Parameter a)'
118        else:
119            param_a = 'Parameter a'
120        vbox.Add(sizer)
121        ix = 0
122        iy = 1
123        sizer.Add(wx.StaticText(self, -1, explanation), (iy, ix),
124                 (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
125        iy += 2
126        sizer.Add(wx.StaticText(self, -1, param_a), (iy, ix),
127                 (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
128        ix += 1
129        sizer.Add(self.tcA,(iy, ix),(1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
130        ix += 1
131        sizer.Add(wx.StaticText(self, -1, '+/-'),
132                  (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
133        ix += 1
134        sizer.Add(self.tcErrA, (iy, ix), (1, 1),
135                  wx.EXPAND|wx.ADJUST_MINSIZE, 0)
136        iy += 1
137        ix = 0
138        sizer.Add(wx.StaticText(self, -1, 'Parameter b'), (iy, ix),(1, 1),
139                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
140        ix += 1
141        sizer.Add(self.tcB, (iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
142        ix += 1
143        sizer.Add(wx.StaticText(self, -1, '+/-'), (iy, ix),
144                  (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
145        ix += 1
146        sizer.Add(self.tcErrB, (iy, ix), (1, 1),
147                   wx.EXPAND|wx.ADJUST_MINSIZE, 0)
148        iy += 1
149        ix = 0
150        sizer.Add(wx.StaticText(self, -1, 'Chi2/dof'), (iy, ix), (1, 1),
151                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
152        ix += 1
153        sizer.Add(self.tcChi, (iy, ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
154
155       
156        #sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND, 0)
157        iy += 2
158        ix = 1
159        sizer.Add(wx.StaticText(self, -1, 'Min'), (iy, ix), (1, 1),
160                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
161        ix += 2
162        sizer.Add(wx.StaticText(self, -1, 'Max'), (iy, ix),
163                  (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
164
165        iy += 1
166        ix = 0
167        sizer.Add(wx.StaticText(self, -1, 'Maximum range (linear scale)'),
168                  (iy, ix),(1,1),
169                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
170        ix += 1
171        sizer.Add(self.initXmin, (iy, ix), (1,1),
172                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
173        ix += 2
174        sizer.Add(self.initXmax, (iy, ix), (1,1), 
175                  wx.EXPAND|wx.ADJUST_MINSIZE, 0)
176       
177        iy += 1
178        ix = 0
179        sizer.Add(wx.StaticText(self, -1, 'Fit range of ' + self.xLabel),
180                  (iy, ix), (1, 1),
181                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
182        ix += 1
183        sizer.Add(self.xminFit, (iy, ix), (1, 1),
184                   wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
185        ix += 2
186        sizer.Add(self.xmaxFit, (iy, ix), (1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
187        if self.rg_on:
188            self.SetSize((PNL_WIDTH, PNL_HEIGHT))
189            I0_stxt = wx.StaticText(self, -1, 'I(q=0)')
190            self.I0_tctr = wx.TextCtrl(self, -1, '')
191            self.I0_tctr.SetEditable(False)
192            self.I0_tctr.SetBackgroundColour(_BACKGROUND_COLOR)
193            self.I0err_tctr = wx.TextCtrl(self, -1, '')
194            self.I0err_tctr.SetEditable(False)
195            self.I0err_tctr.SetBackgroundColour(_BACKGROUND_COLOR)
196            Rg_stxt = wx.StaticText(self, -1, 'Rg [A]')
197            Rg_stxt.Show(self.yLabel == "ln(y)" )
198            self.Rg_tctr = wx.TextCtrl(self, -1, '')
199            self.Rg_tctr.SetEditable(False)
200            self.Rg_tctr.SetBackgroundColour(_BACKGROUND_COLOR)
201            self.Rg_tctr.Show(self.yLabel == "ln(y)" )
202            self.Rgerr_tctr = wx.TextCtrl(self, -1, '')
203            self.Rgerr_tctr.SetEditable(False)
204            self.Rgerr_tctr.SetBackgroundColour(_BACKGROUND_COLOR)
205            self.Rgerr_tctr.Show(self.yLabel == "ln(y)" )
206            self.Rgerr_pm = wx.StaticText(self, -1, '+/-')
207            self.Rgerr_pm.Show(self.yLabel == "ln(y)" )
208            Diameter_stxt = wx.StaticText(self, -1, 'Rod Diameter [A]')
209            Diameter_stxt.Show(self.yLabel == "ln(y*x)")
210            self.Diameter_tctr = wx.TextCtrl(self, -1, '')
211            self.Diameter_tctr.SetEditable(False)
212            self.Diameter_tctr.SetBackgroundColour(_BACKGROUND_COLOR)
213            self.Diameter_tctr.Show(self.yLabel == "ln(y*x)")
214            self.Diameter_pm = wx.StaticText(self, -1, '+/-')
215            self.Diameter_pm.Show(self.yLabel == "ln(y*x)")
216            self.Diametererr_tctr = wx.TextCtrl(self, -1, '')
217            self.Diametererr_tctr.SetEditable(False)
218            self.Diametererr_tctr.SetBackgroundColour(_BACKGROUND_COLOR)
219            self.Diametererr_tctr.Show(self.yLabel == "ln(y*x)")
220            RgQmin_stxt = wx.StaticText(self, -1, 'Rg*Qmin')
221            self.RgQmin_tctr = wx.TextCtrl(self, -1, '')
222            self.RgQmin_tctr.SetEditable(False)
223            self.RgQmin_tctr.SetBackgroundColour(_BACKGROUND_COLOR)
224            RgQmax_stxt = wx.StaticText(self, -1, 'Rg*Qmax')
225            self.RgQmax_tctr = wx.TextCtrl(self, -1, '')
226            self.RgQmax_tctr.SetEditable(False)
227            self.RgQmax_tctr.SetBackgroundColour(_BACKGROUND_COLOR)
228
229            iy += 2
230            ix = 0
231            sizer.Add(I0_stxt, (iy, ix), (1,1),
232                                    wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
233            ix += 1
234            sizer.Add(self.I0_tctr, (iy, ix), (1,1),
235                                    wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
236            ix += 1
237            sizer.Add(wx.StaticText(self, -1, '+/-'), (iy, ix),
238                                    (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
239            ix += 1
240            sizer.Add(self.I0err_tctr, (iy, ix), (1,1), 
241                                    wx.EXPAND|wx.ADJUST_MINSIZE, 0)
242           
243            iy += 1
244            ix = 0
245            sizer.Add(Rg_stxt, (iy, ix),(1,1),
246                                    wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
247            ix += 1
248            sizer.Add(self.Rg_tctr, (iy, ix), (1,1),
249                                    wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
250   
251            ix += 1
252            sizer.Add(self.Rgerr_pm, (iy, ix),
253                                    (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
254            ix += 1
255            sizer.Add(self.Rgerr_tctr, (iy, ix), (1,1), 
256                                    wx.EXPAND|wx.ADJUST_MINSIZE, 0)
257            iy += 1
258            ix = 0
259            sizer.Add(Diameter_stxt, (iy, ix),(1,1),
260                                    wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
261            ix += 1
262            sizer.Add(self.Diameter_tctr, (iy, ix), (1,1),
263                                    wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
264   
265            ix += 1
266            sizer.Add(self.Diameter_pm, (iy, ix),
267                                    (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
268            ix += 1
269            sizer.Add(self.Diametererr_tctr, (iy, ix), (1,1), 
270                                    wx.EXPAND|wx.ADJUST_MINSIZE, 0)
271            iy += 1
272            ix = 0
273            sizer.Add(RgQmin_stxt, (iy, ix),(1,1),
274                                    wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
275            ix += 1
276            sizer.Add(self.RgQmin_tctr, (iy, ix), (1,1),
277                                    wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
278            iy += 1
279            ix = 0
280            sizer.Add(RgQmax_stxt, (iy, ix),(1,1),
281                                    wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
282            ix += 1
283            sizer.Add(self.RgQmax_tctr, (iy, ix), (1,1),
284                                    wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 0)
285           
286        iy += 1
287        ix = 1
288       
289        vbox.Add(self.static_line_1, 0, wx.EXPAND, 0)
290        sizer_button = wx.BoxSizer(wx.HORIZONTAL)
291        sizer_button.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
292        sizer_button.Add(self.btFit, 0, wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
293        sizer_button.Add(self.btClose, 0,
294                          wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
295        vbox.Add(sizer_button, 0, wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
296       
297        sizer.Add(self.btFit, (iy, ix), (1,1), wx.LEFT|wx.ADJUST_MINSIZE, 0)
298        #panel.SetSizer(sizer)
299        self.SetSizer(vbox)
300        self.Centre()
301        # Receives the type of model for the fitting
302        from LineModel import LineModel
303        self.model = LineModel()
304        #Display the fittings values
305        self.default_A = self.model.getParam('A')
306        self.default_B = self.model.getParam('B')
307        self.cstA = fittings.Parameter(self.model, 'A', self.default_A)
308        self.cstB = fittings.Parameter(self.model, 'B', self.default_B)
309       
310        # Set default value of parameter in fit dialog
311        if self.Avalue == None:
312            self.tcA.SetValue(format_number(self.default_A))
313        else:
314            self.tcA.SetLabel(format_number(self.Avalue))
315        if self.Bvalue == None:
316            self.tcB.SetValue(format_number(self.default_B))
317        else:
318            self.tcB.SetLabel(format_number(self.Bvalue))
319        if self.ErrAvalue == None:
320            self.tcErrA.SetLabel(format_number(0.0))
321        else:
322            self.tcErrA.SetLabel(format_number(self.ErrAvalue))
323        if self.ErrBvalue == None:
324            self.tcErrB.SetLabel(format_number(0.0))
325        else:
326            self.tcErrB.SetLabel(format_number(self.ErrBvalue))
327        if self.Chivalue == None:
328            self.tcChi.SetLabel(format_number(0.0))
329        else:
330            self.tcChi.SetLabel(format_number(self.Chivalue))
331        if self.plottable.x != []:
332            #store the values of View in self.x,self.y,self.dx,self.dy
333            self.x, self.y, self.dx, \
334                     self.dy = self.plottable.returnValuesOfView()
335            try:
336                self.mini = self.floatForwardTransform(min(self.x))
337            except:
338                self.mini = "Invalid"
339            try:
340                self.maxi = self.floatForwardTransform(max(self.x))
341            except:
342                self.maxi = "Invalid"
343
344            self.initXmin.SetValue(format_number(min(self.plottable.x)))
345            self.initXmax.SetValue(format_number(max(self.plottable.x)))
346            self.mini = min(self.x)
347            self.maxi = max(self.x)
348            self.xminFit.SetValue(format_number(self.mini))
349            self.xmaxFit.SetValue(format_number(self.maxi))
350   
351    def register_close(self, owner):
352        """
353        Method to register the close event to a parent
354        window that needs notification when the dialog
355        is closed
356       
357        :param owner: parent window
358       
359        """
360        self._registered_close = owner
361       
362    def _on_close(self, event):
363        """
364        Close event.
365        Notify registered owner if available.
366        """
367        event.Skip()
368        if self._registered_close is not None:
369            self._registered_close()
370       
371    def _onFit(self, event):
372        """
373        Performs the fit. Receive an event when clicking on
374        the button Fit.Computes chisqr ,
375        A and B parameters of the best linear fit y=Ax +B
376        Push a plottable to
377        """
378        tempx = []
379        tempy = []
380        tempdy = []
381           
382        # Check if View contains a x array .we online fit when x exits
383        # makes transformation for y as a line to fit
384        if self.x != []:
385            if(self.checkFitValues(self.xminFit) == True):
386                #Check if the field of Fit Dialog contain values
387                # and use the x max and min of the user
388                #xminView,xmaxView = self._checkVal(self.xminFit.GetValue(),
389                #self.xmaxFit.GetValue())
390                if not self._checkVal(self.xminFit, self.xmaxFit):
391                    return
392                xminView = float(self.xminFit.GetValue())
393                xmaxView = float(self.xmaxFit.GetValue())
394                #xmin = self.floatInvTransform(xminView)
395                #xmax = self.floatInvTransform(xmaxView)
396                xmin = xminView
397                xmax = xmaxView
398                # Store the transformed values of view x, y,dy
399                # in variables  before the fit
400                if self.yLabel.lower() == "log10(y)":
401                    if (self.xLabel.lower() == "log10(x)"):
402                        for i in range(len(self.x)):
403                            if self.x[i] >= math.log10(xmin):
404                                tempy.append(math.log10(self.y[i]))
405                                tempdy.append(transform.errToLogX(self.y[i],
406                                                        0, self.dy[i], 0))
407                    else:
408                        for i in range(len(self.y)):
409                            tempy.append(math.log10(self.y[i]))
410                            tempdy.append(transform.errToLogX(self.y[i],
411                                                            0, self.dy[i], 0))
412                else:
413                    tempy = self.y
414                    tempdy = self.dy
415               
416                if (self.xLabel.lower() == "log10(x)"):
417                    for x_i in self.x:
418                        if x_i >= math.log10(xmin):
419                            tempx.append(math.log10(x_i))
420                else:
421                    tempx = self.x
422             
423                #Find the fitting parameters
424                # Always use the same defaults, so that fit history
425                #doesn't play a role!
426                self.cstA = fittings.Parameter(self.model, 'A', self.default_A)
427                self.cstB = fittings.Parameter(self.model, 'B', self.default_B)
428               
429                if (self.xLabel.lower() == "log10(x)"):
430                    tempdy = numpy.asarray(tempdy)
431                    tempdy[tempdy == 0] = 1
432                    chisqr, out, cov = fittings.sansfit(self.model,
433                                                        [self.cstA, self.cstB],
434                                                        tempx, tempy,
435                                                        tempdy,
436                                                        math.log10(xmin),
437                                                        math.log10(xmax))
438                else:
439                    tempdy = numpy.asarray(tempdy)
440                    tempdy[tempdy == 0] = 1
441                    chisqr, out, cov = fittings.sansfit(self.model,
442                                                        [self.cstA, self.cstB],
443                                                        tempx, tempy, tempdy,
444                                                        xminView, xmaxView)
445                # Use chi2/dof
446                if len(tempx) > 0:
447                    chisqr = chisqr/len(tempx)
448               
449                #Check that cov and out are iterable before displaying them
450                if cov == None:
451                    errA = 0.0
452                    errB = 0.0
453                else:
454                    errA = math.sqrt(cov[0][0])
455                    errB = math.sqrt(cov[1][1])
456                if out == None:
457                    cstA = 0.0
458                    cstB = 0.0
459                else:
460                    cstA = out[0]
461                    cstB = out[1]
462                # Reset model with the right values of A and B
463                self.model.setParam('A', float(cstA))
464                self.model.setParam('B', float(cstB))
465               
466                tempx = []
467                tempy = []
468                y_model = 0.0
469                # load tempy with the minimum transformation
470               
471                if self.xLabel == "log10(x)":
472                    y_model = self.model.run(math.log10(xmin))
473                    tempx.append(xmin)
474                else:
475                    y_model = self.model.run(xminView)
476                    tempx.append(xminView)
477                   
478                if self.yLabel == "log10(y)":
479                    tempy.append(math.pow(10, y_model))
480                else:
481                    tempy.append(y_model)
482                   
483                # load tempy with the maximum transformation
484                if self.xLabel == "log10(x)":
485                    y_model = self.model.run(math.log10(xmax))
486                    tempx.append(xmax)
487                else:
488                    y_model = self.model.run(xmaxView)
489                    tempx.append(xmaxView)
490                   
491                if self.yLabel == "log10(y)":
492                    tempy.append(math.pow(10, y_model))
493                else:
494                    tempy.append(y_model)
495                #Set the fit parameter display when  FitDialog is opened again
496                self.Avalue = cstB
497                self.Bvalue = cstA
498                self.ErrAvalue = errA
499                self.ErrBvalue = errB
500                self.Chivalue = chisqr
501                self.push_data(tempx, tempy, xminView, xmaxView,
502                               xmin, xmax, self._ongetValues())
503               
504                # Display the fitting value on the Fit Dialog
505                self._onsetValues(cstB, cstA, errA, errB, chisqr)
506               
507    def _onsetValues(self, cstA, cstB, errA, errB, Chi):
508        """
509        Display  the value on fit Dialog
510        """
511        rg = None
512        self.tcA.SetValue(format_number(cstA))
513        self.tcB.SetValue(format_number(cstB))
514        self.tcErrA.SetValue(format_number(errA))
515        self.tcErrB.SetValue(format_number(errB))
516        self.tcChi.SetValue(format_number(Chi))
517        if self.rg_on:
518            if self.Rg_tctr.IsShown():
519                rg = numpy.sqrt(-3 * float(cstA))
520                value = format_number(rg)
521                self.Rg_tctr.SetValue(value)
522                if self.I0_tctr.IsShown():
523                    val = numpy.exp(cstB)
524                    self.I0_tctr.SetValue(format_number(val))
525            if self.Rgerr_tctr.IsShown():
526                if rg != None and rg != 0:
527                    value = format_number(3 * float(cstA) / (2 * rg))
528                else:
529                    value =''
530                self.Rgerr_tctr.SetValue(value)
531                if self.I0err_tctr.IsShown():
532                    val = numpy.abs(numpy.exp(cstB) - numpy.exp(cstB + errB))
533                    self.I0err_tctr.SetValue(format_number(val))
534            if self.Diameter_tctr.IsShown():
535                rg = 4 * numpy.sqrt(-float(cstA))
536                value = format_number(rg)
537                self.Diameter_tctr.SetValue(value)
538            if self.Diametererr_tctr.IsShown():
539                if rg != None and rg != 0:
540                    value = format_number(8 * float(cstA) / rg)
541                else:
542                    value =''
543                self.Diametererr_tctr.SetValue(value)
544            if self.RgQmin_tctr.IsShown():
545                value = format_number(rg * self.mini)
546                self.RgQmin_tctr.SetValue(value)
547            if self.RgQmax_tctr.IsShown():
548                value = format_number(rg * self.maxi)
549                self.RgQmax_tctr.SetValue(value)
550               
551    def _ongetValues(self):
552        """
553        Display  the value on fit Dialog
554        """
555        return self.Avalue, self.Bvalue, self.ErrAvalue, \
556                            self.ErrBvalue, self.Chivalue
557   
558    def _checkVal(self, usermin, usermax):
559        """
560        Ensure that fields parameter contains a min and a max value
561        within x min and x max range
562        """
563        self.mini = float(self.xminFit.GetValue())
564        self.maxi = float(self.xmaxFit.GetValue())
565        flag = True
566        try:
567            mini = float(usermin.GetValue())
568            maxi = float(usermax.GetValue())
569            if mini < maxi:
570                usermin.SetBackgroundColour(wx.WHITE)
571                usermin.Refresh()
572            else:
573                flag = False
574                usermin.SetBackgroundColour("pink")
575                usermin.Refresh()
576        except:
577            # Check for possible values entered
578            flag = False
579            usermin.SetBackgroundColour("pink")
580            usermin.Refresh()
581     
582        return flag
583           
584    def floatForwardTransform(self, x):
585        """
586        transform a float.
587        """
588        #TODO: refactor this with proper object-oriented design
589        # This code stinks.
590        if(self.xLabel == "x"):
591            return transform.toX(x)
592        if(self.xLabel == "x^(2)"):
593            return transform.toX2(x)
594        if(self.xLabel == "ln(x)"):
595            return transform.toLogX(x)
596        if(self.xLabel == "log10(x)"):
597            return math.log10(x)
598                   
599    def floatTransform(self, x):
600        """
601        transform a float.It is use to determine the x.
602        View min and x.View max for values
603        not in x
604        """
605        #TODO: refactor this with proper object-oriented design
606        # This code stinks.
607        if(self.xLabel == "x"):
608            return transform.toX(x)
609        if(self.xLabel == "x^(2)"):
610            return transform.toX2(x)
611        if(self.xLabel == "ln(x)"):
612            return transform.toLogX(x)
613        if(self.xLabel == "log10(x)"):
614            if x > 0:
615                return x
616            else:
617                raise ValueError, "cannot compute log of a negative number"
618           
619    def floatInvTransform(self, x):
620        """
621        transform a float.It is use to determine the x.View min and x.View
622        max for values not in x
623       
624        """
625        #TODO: refactor this. This is just a hack to make the
626        # functionality work without rewritting the whole code
627        # with good design (which really should be done...).
628        if(self.xLabel == "x^(2)"):
629            return math.sqrt(x)
630       
631        elif(self.xLabel == "log10(x)"):
632            return math.pow(10, x)
633       
634        elif(self.xLabel == "ln(x)"):
635            return math.exp(x)
636        return x
637           
638    def checkFitValues(self, item):
639        """
640            Check the validity of input values
641        """
642        flag = True
643        value = item.GetValue()
644        # Check for possible values entered
645        if (self.xLabel == "log10(x)"):  #or self.xLabel=="ln(x)"):
646            if(float(value) > 0):
647                item.SetBackgroundColour(wx.WHITE)
648                item.Refresh()
649            else:
650                flag = False
651                item.SetBackgroundColour("pink")
652                item.Refresh()
653        return flag
654       
655    def setFitRange(self, xmin, xmax, xminTrans, xmaxTrans):
656        """
657        Set fit parameters
658        """
659        self.xminFit.SetValue(format_number(xmin))
660        self.xmaxFit.SetValue(format_number(xmax))
661       
662    def set_fit_region(self, xmin, xmax):
663        """
664        Set the fit region
665        :param xmin: minimum x-value to be included in fit
666        :param xmax: maximum x-value to be included in fit
667        """
668        # Check values
669        try:
670            float(xmin)
671            float(xmax)
672        except:
673            msg = "LinearFit.set_fit_region: fit range must be floats"
674            raise ValueError, msg
675        self.xminFit.SetValue(format_number(xmin))
676        self.xmaxFit.SetValue(format_number(xmax))
677 
678 
679class MyApp(wx.App):
680    """
681    """
682    def OnInit(self):
683        """
684        """
685        wx.InitAllImageHandlers()
686        plot = Theory1D([], [])
687        dialog = LinearFit(parent=None, plottable=plot,
688                           push_data=self.onFitDisplay,
689                           transform=self.returnTrans,
690                            title='Linear Fit')
691        if dialog.ShowModal() == wx.ID_OK:
692            pass
693        dialog.Destroy()
694        return 1
695   
696    def onFitDisplay(self, tempx, tempy, xminView, xmaxView, xmin, xmax, func):
697        """
698        """
699        pass
700       
701    def returnTrans(self):
702        """
703        """
704        return '', '', 0, 0, 0, 0, 0
Note: See TracBrowser for help on using the repository browser.