source: sasview/invariantview/perspectives/invariant/invariant_details.py @ 3fab6ef

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

rpitn the correct message on details panel

  • Property mode set to 100644
File size: 17.5 KB
RevLine 
[9ce7641c]1
2import wx
3import sys
[45802d4]4
[9ce7641c]5import numpy
6from sans.guiframe.utils import format_number, check_float
[518d35d]7from invariant_widgets import OutputTextCtrl
[9ce7641c]8# Dimensions related to chart
9RECTANGLE_WIDTH  = 400.0 
10RECTANGLE_HEIGHT = 20
11#Invariant panel size
12_BOX_WIDTH = 76
[d0cc0bbc]13
14#scale to use for a bar of value zero
15RECTANGLE_SCALE  = 0.0001
16DEFAULT_QSTAR = 1.0 
[9ce7641c]17 
18if sys.platform.count("win32")>0:
19    _STATICBOX_WIDTH = 450
20    PANEL_WIDTH = 500
[d0cc0bbc]21    PANEL_HEIGHT = 430
[9ce7641c]22    FONT_VARIANT = 0
23else:
24    _STATICBOX_WIDTH = 480
25    PANEL_WIDTH = 530
[d0cc0bbc]26    PANEL_HEIGHT = 430
[9ce7641c]27    FONT_VARIANT = 1
28   
[d0cc0bbc]29 
[9ce7641c]30   
[d0cc0bbc]31class InvariantContainer(wx.Object):
[45802d4]32    """
33        This class stores some values resulting resulting from invariant
34        calculations. Given the value of total invariant, this class can also
35        determine the percentage of invariants resulting from extrapolation.
36    """
[d0cc0bbc]37    def __init__(self):
38        #invariant at low range
39        self.qstar_low = 0.0
40        #invariant at low range error
41        self.qstar_low_err = 0.0
42        #invariant
43        self.qstar = 0.0
44        #invariant error
45        self.qstar_err = 0.0
46        #invariant at high range
47        self.qstar_high = 0.0
48        #invariant at high range error
49        self.qstar_high_err = 0.0
50        #invariant total
51        self.qstar_total = None
52        #invariant error
53        self.qstar_total_err = None
54        #scale
55        self.qstar_low_percent = 0.0
56        self.qstar_high_percent = 0.0
57        self.qstar_percent = 0.0
58        # warning message
59        self.existing_warning = False
60        self.warning_msg = "No Details on calculations available...\n"
61       
62    def compute_percentage(self):
63        """
64            Compute percentage of each invariant
65        """
66        if self.qstar_total is not None and self.qstar_total != 0:
67            #compute invariant percentage
68            if self.qstar is None:
69                self.qstar = 0.0
70            self.qstar_percent = self.qstar/self.qstar_total
71            #compute low q invariant percentage
72            if self.qstar_low is None:
73                self.qstar_low = 0.0
74            self.qstar_low_percent = self.qstar_low/self.qstar_total
75            #compute high q invariant percentage
76            if self.qstar_high is None:
77                self.qstar_high = 0.0
78            self.qstar_high_percent = self.qstar_high/self.qstar_total
79        self.check_values()
80   
81    def check_values(self):
82        """
83            check the validity if invariant
84        """
85        #warning to the user when the extrapolated invariant is greater than %5
[3fab6ef]86        msg = ''
[d0cc0bbc]87        if self.qstar_low_percent >= 0.05:
88            self.existing_warning = True
[3fab6ef]89            msg += "Extrapolated contribution at Low Q is higher "
90            msg += "than 5% of the invariant.\n"
[d0cc0bbc]91        if self.qstar_high_percent >= 0.05:
92            self.existing_warning = True
[3fab6ef]93            msg += "Extrapolated contribution at High Q is higher "
94            msg += "than 5% of the invariant.\n"
[d0cc0bbc]95        if self.qstar_low_percent + self.qstar_high_percent >= 0.05:
96            self.existing_warning = True
[3fab6ef]97            msg += "The sum of all extrapolated contributions is higher "
98            msg += "than 5% of the invariant.\n"
[d0cc0bbc]99           
100        if self.existing_warning:
[3fab6ef]101            self.warning_msg = ''
102            self.warning_msg += msg
[d0cc0bbc]103            self.warning_msg += "The calculations are likely to be unreliable!\n"
104        else:
105            self.warning_msg = "No Details on calculations available...\n"
106           
[d3fac18]107class InvariantDetailsPanel(wx.Dialog):
[9ce7641c]108    """
109        This panel describes proportion of invariants
110    """
[45802d4]111    def __init__(self, parent=None, id=-1, qstar_container=None, 
112                                    title="Invariant Details",
113                                    size=(PANEL_WIDTH, PANEL_HEIGHT)):
[f75ea4a]114        wx.Dialog.__init__(self, parent=parent, id=id,title=title,size=size)
115       
116        #Font size
117        self.SetWindowVariant(variant=FONT_VARIANT)
118        self.parent = parent
119        #self.qstar_container
120        self.qstar_container = qstar_container
121        #warning message
122        self.warning_msg = self.qstar_container.warning_msg
[d0cc0bbc]123   
[f75ea4a]124        #Define scale of each bar
125        self.low_inv_percent = self.qstar_container.qstar_low_percent
126        self.low_scale = self.get_scale(percentage=self.low_inv_percent,
127                                         scale_name="Extrapolated at Low Q")
128        self.inv_percent = self.qstar_container.qstar_percent
129        self.inv_scale = self.get_scale(percentage=self.inv_percent, 
130                                            scale_name="Inv in Q range")
131        self.high_inv_percent = self.qstar_container.qstar_high_percent
132        self.high_scale = self.get_scale(percentage=self.high_inv_percent,
133                                         scale_name="Extrapolated at High Q")
134       
135        #Default color the extrapolation bar is grey
136        self.extrapolation_color_low = wx.Colour(169,  169, 168, 128)
137        self.extrapolation_color_high = wx.Colour(169,  169, 168, 128)
138        #change color of high and low bar when necessary
139        self.set_color_bar()
140        #draw the panel itself
141        self._do_layout()
142        self.set_values()
143 
[9ce7641c]144    def _define_structure(self):
145        """
146            Define main sizers needed for this panel
147        """
148        #Box sizers must be defined first before defining buttons/textctrls (MAC).
149        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
150        #Sizer related to chart
151        chart_box = wx.StaticBox(self, -1, "Invariant Chart")
152        self.chart_sizer = wx.StaticBoxSizer(chart_box, wx.VERTICAL)
[d0cc0bbc]153        self.chart_sizer.SetMinSize((PANEL_WIDTH - 50,100))
[9ce7641c]154        #Sizer related to invariant values
155        self.invariant_sizer =  wx.GridBagSizer(4, 4)
[d0cc0bbc]156        invariant_box = wx.StaticBox(self, -1, "Numerical Values")
157        self.invariant_box_sizer = wx.StaticBoxSizer(invariant_box,
158                                                      wx.HORIZONTAL)
159
160        self.invariant_box_sizer.SetMinSize((PANEL_WIDTH - 50,-1))
[9ce7641c]161        #Sizer related to warning message
162        warning_box = wx.StaticBox(self, -1, "Warning")
163        self.warning_sizer = wx.StaticBoxSizer(warning_box, wx.VERTICAL)
[da87bce]164        self.warning_sizer.SetMinSize((PANEL_WIDTH-50,-1))
[9ce7641c]165        #Sizer related to button
166        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
167     
168    def _layout_shart(self):
169        """
170            Draw widgets related to chart
171        """
172        self.panel_chart = wx.Panel(self)
173        self.panel_chart.Bind(wx.EVT_PAINT, self.on_paint)
174        self.chart_sizer.Add(self.panel_chart, 1, wx.EXPAND|wx.ALL, 0)
175       
176    def _layout_invariant(self):
177        """
178            Draw widgets related to invariant
179        """
180        uncertainty = "+/-" 
[d0cc0bbc]181        unit_invariant = '[1/(cm * A)]'
[9ce7641c]182     
183        invariant_txt = wx.StaticText(self, -1, 'Invariant')
[518d35d]184        self.invariant_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH,-1))
[9ce7641c]185        self.invariant_tcl.SetToolTipString("Invariant in the data set's Q range.")
[518d35d]186        self.invariant_err_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH,-1))
[9ce7641c]187        self.invariant_err_tcl.SetToolTipString("Uncertainty on the invariant.")
188        invariant_units_txt = wx.StaticText(self, -1, unit_invariant)
189       
190        invariant_low_txt = wx.StaticText(self, -1, 'Invariant in low-Q region')
[518d35d]191        self.invariant_low_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH,-1))
[9ce7641c]192        self.invariant_low_tcl.SetToolTipString("Invariant computed with the extrapolated low-Q data.")
[518d35d]193        self.invariant_low_err_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH,-1))
[9ce7641c]194        self.invariant_low_err_tcl.SetToolTipString("Uncertainty on the invariant.")
195        invariant_low_units_txt = wx.StaticText(self, -1,  unit_invariant)
196       
197        invariant_high_txt = wx.StaticText(self, -1, 'Invariant in high-Q region')
[518d35d]198        self.invariant_high_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH,-1))
[9ce7641c]199        self.invariant_high_tcl.SetToolTipString("Invariant computed with the extrapolated high-Q data")
[518d35d]200        self.invariant_high_err_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH,-1))
[9ce7641c]201        self.invariant_high_err_tcl.SetToolTipString("Uncertainty on the invariant.")
202        invariant_high_units_txt = wx.StaticText(self, -1,  unit_invariant)
203   
204        #Invariant low
[d0cc0bbc]205        iy = 0
[9ce7641c]206        ix = 0 
207        self.invariant_sizer.Add(invariant_low_txt, (iy, ix), (1,1),
208                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
209        ix += 1
210        self.invariant_sizer.Add(self.invariant_low_tcl, (iy, ix), (1,1),
211                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
212        ix += 1
213        self.invariant_sizer.Add( wx.StaticText(self, -1, uncertainty),
214                         (iy, ix),(1,1),wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
215        ix += 1
216        self.invariant_sizer.Add(self.invariant_low_err_tcl, (iy, ix), (1,1),
217                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
218        ix += 1
219        self.invariant_sizer.Add(invariant_low_units_txt
220                         ,(iy, ix),(1,1),wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
221        #Invariant
222        iy += 1
223        ix = 0 
224        self.invariant_sizer.Add(invariant_txt, (iy, ix), (1,1),
225                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
226        ix += 1
227        self.invariant_sizer.Add(self.invariant_tcl, (iy, ix), (1,1),
228                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
229        ix += 1
230        self.invariant_sizer.Add(wx.StaticText(self, -1, uncertainty),
231                         (iy, ix),(1,1),wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
232        ix += 1
233        self.invariant_sizer.Add(self.invariant_err_tcl, (iy, ix), (1,1),
234                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
235        ix +=1
236        self.invariant_sizer.Add(invariant_units_txt
237                         ,(iy, ix),(1,1),wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
238        #Invariant high
239        iy += 1
240        ix = 0 
241        self.invariant_sizer.Add(invariant_high_txt, (iy, ix), (1,1),
242                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
243        ix += 1
244        self.invariant_sizer.Add(self.invariant_high_tcl, (iy, ix), (1,1),
245                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
246        ix += 1
247        self.invariant_sizer.Add(wx.StaticText(self, -1, uncertainty),
248                         (iy, ix),(1,1),wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
249        ix += 1
250        self.invariant_sizer.Add(self.invariant_high_err_tcl, (iy, ix), (1,1),
251                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
252        ix += 1
253        self.invariant_sizer.Add(invariant_high_units_txt
[d0cc0bbc]254                         ,(iy, ix),(1,1),wx.EXPAND|wx.ADJUST_MINSIZE, 0)
255        self.invariant_box_sizer.Add(self.invariant_sizer, 0, wx.TOP|wx.BOTTOM, 10) 
[9ce7641c]256       
257    def _layout_warning(self):
258        """
259            Draw widgets related to warning
260        """
261        #Warning [string]
[3fab6ef]262        self.warning_msg_txt = wx.StaticText(self, -1, self.warning_msg) 
[d0cc0bbc]263        if self.qstar_container.existing_warning:
264            self.warning_msg_txt.SetForegroundColour('red') 
[277fad8]265        self.warning_sizer.AddMany([(self.warning_msg_txt, 0,
266                                     wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 10)])
[9ce7641c]267       
268    def _layout_button(self):
269        """
270            Draw widgets related to button
271        """
272        #Close button
273        id = wx.NewId()
274        button_ok = wx.Button(self, id, "Ok")
275        button_ok.SetToolTipString("Give Details on Computation")
276        self.Bind(wx.EVT_BUTTON, self.on_close, id=id)
[da87bce]277        self.button_sizer.AddMany([((20,20), 0 , wx.LEFT, 350),
[9ce7641c]278                                   (button_ok, 0 , wx.RIGHT, 10)])
279    def _do_layout(self):
280        """
281            Draw window content
282        """
283        self._define_structure()
284        self._layout_shart()
285        self._layout_invariant()
286        self._layout_warning()
287        self._layout_button()
[d0cc0bbc]288        self.main_sizer.AddMany([(self.chart_sizer, 0, wx.ALL, 10),
289                                 ( self.invariant_box_sizer, 0, wx.ALL, 10),
[9ce7641c]290                                  (self.warning_sizer, 0, wx.ALL, 10),
291                                  (self.button_sizer, 0, wx.ALL, 10)])
292        self.SetSizer(self.main_sizer)
[d3fac18]293       
[9ce7641c]294       
295    def set_values(self):
296        """
297            Set value of txtcrtl
298        """
299        self.invariant_tcl.SetValue(format_number(self.qstar_container.qstar))
300        self.invariant_err_tcl.SetValue(format_number(self.qstar_container.qstar_err)) 
301        self.invariant_low_tcl.SetValue(format_number(self.qstar_container.qstar_low))
302        self.invariant_low_err_tcl.SetValue(format_number(self.qstar_container.qstar_low_err)) 
303        self.invariant_high_tcl.SetValue(format_number(self.qstar_container.qstar_high))
304        self.invariant_high_err_tcl.SetValue(format_number(self.qstar_container.qstar_high_err)) 
[d0cc0bbc]305
306    def get_scale(self, percentage, scale_name='scale'):
[9ce7641c]307        """
[d0cc0bbc]308            Check scale receive in this panel.
[9ce7641c]309        """
310        try: 
[d0cc0bbc]311            if percentage is None or percentage == 0.0:
312                 percentage = RECTANGLE_SCALE
313            percentage = float(percentage) 
[9ce7641c]314        except:
[d0cc0bbc]315            percentage = RECTANGLE_SCALE
[9ce7641c]316            self.warning_msg += "Receive an invalid scale for %s\n"
[d0cc0bbc]317            self.warning_msg += "check this value : %s\n"%(str(scale_name),str(percentage))
318        return  percentage
[9ce7641c]319   
320    def set_color_bar(self):
321        """
322            Change the color for low and high bar when necessary
323        """
324        #warning to the user when the extrapolated invariant is greater than %5
325        if self.low_scale >= 0.05:
326            self.extrapolation_color_low = wx.Colour(255,  0, 0, 128)
327        if self.high_scale >= 0.05:
328            self.extrapolation_color_high = wx.Colour(255,  0, 0, 128)
[d0cc0bbc]329           
[9ce7641c]330    def on_close(self, event):
331        """
332            Close the current window
333        """
334        self.Close()
[d3fac18]335     
[9ce7641c]336    def on_paint(self, event):
337        """
338            Draw the chart
339        """
340        dc = wx.PaintDC(self.panel_chart)
341        try:
342            gc = wx.GraphicsContext.Create(dc)
343        except NotImplementedError:
344            dc.DrawText("This build of wxPython does not support the wx.GraphicsContext "
345                        "family of classes.", 25, 25)
346            return
347        #Start the drawing
348        font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
349        font.SetWeight(wx.BOLD)
350        gc.SetFont(font)
351        # Draw a rectangle
352        path = gc.CreatePath()
353        path.AddRectangle(-RECTANGLE_WIDTH/2,-RECTANGLE_HEIGHT/2,
354                          RECTANGLE_WIDTH/2,RECTANGLE_HEIGHT/2)
[d0cc0bbc]355        x_origine = 20
[9ce7641c]356        y_origine = 15
357        #Draw low rectangle
358        gc.PushState()       
[d0cc0bbc]359        label = "Q* At Low-Q"
[9ce7641c]360        PathFunc = gc.DrawPath
361        w, h = gc.GetTextExtent(label)
362        gc.DrawText(label, x_origine, y_origine)
363        #Translate the rectangle
364        x_center = x_origine + RECTANGLE_WIDTH * self.low_scale/2 + w +10
365        y_center = y_origine + h
366        gc.Translate(x_center, y_center)   
367        gc.SetPen(wx.Pen("black", 1))
368        gc.SetBrush(wx.Brush(self.extrapolation_color_low))
[d0cc0bbc]369        low_percent = format_number(self.low_inv_percent*100)+ '%'
370        x_center = 20
371        y_center = -h
372        gc.DrawText(low_percent, x_center, y_center)
[9ce7641c]373        # Increase width by self.low_scale
374        gc.Scale(self.low_scale, 1.0) 
375        PathFunc(path)
376        gc.PopState() 
377        #Draw rectangle for invariant   
378        gc.PushState()    # save it again
379        y_origine += 20         
[d0cc0bbc]380        gc.DrawText("Q* In range", x_origine, y_origine)
[9ce7641c]381        # offset to the lower part of the window
382        x_center = x_origine + RECTANGLE_WIDTH * self.inv_scale/2 + w + 10
383        y_center = y_origine + h
384        gc.Translate(x_center, y_center)
385        # 128 == half transparent
386        gc.SetBrush(wx.Brush(wx.Colour(67,  208,  128, 128))) 
387        # Increase width by self.inv_scale
[d0cc0bbc]388        inv_percent = format_number(self.inv_percent*100)+ '%'
389        x_center = 20 
390        y_center = -h
391        gc.DrawText(inv_percent, x_center, y_center)
[9ce7641c]392        gc.Scale(self.inv_scale, 1.0)   
393        gc.DrawPath(path)
394        gc.PopState()
395        # restore saved state
396        #Draw rectangle for high invariant
397        gc.PushState() 
398        y_origine += 20 
[d0cc0bbc]399        gc.DrawText("Q* At High-Q", x_origine, y_origine) 
[9ce7641c]400        #define the position of the new rectangle
401        x_center = x_origine + RECTANGLE_WIDTH * self.high_scale/2 + w + 10
402        y_center = y_origine + h
403        gc.Translate(x_center, y_center)
404        gc.SetBrush(wx.Brush(self.extrapolation_color_high)) 
405        # increase scale by self.high_scale
[d0cc0bbc]406        high_percent = format_number(self.high_inv_percent*100)+ '%'
407        x_center = 20
408        y_center = -h
409        gc.DrawText(high_percent, x_center, y_center)
410       
[9ce7641c]411        gc.Scale(self.high_scale, 1.0) 
412        gc.DrawPath(path)
413        gc.PopState()
[d3fac18]414
[45802d4]415
[9ce7641c]416if __name__ =="__main__":
417    app  = wx.App()
[d3fac18]418    container = InvariantContainer()
[d0cc0bbc]419    container.qstar_total = 100.0
420    container.qstar = 15.0
421    container.qstar_low = 0.001
422    container.qstar_high = 100.0
423    container.compute_percentage()
[45802d4]424    dlg = InvariantDetailsPanel(qstar_container=container)
425    dlg.ShowModal()
[9ce7641c]426    app.MainLoop()
Note: See TracBrowser for help on using the repository browser.