source: sasview/src/sas/perspectives/calculator/gen_scatter_panel.py @ 60dca65c

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 60dca65c was 60dca65c, checked in by butler, 9 years ago

test mac fix for positioning of top level panel - test uses
gen_scatter_panel as the example.

  • Property mode set to 100644
File size: 72.4 KB
Line 
1"""
2Generic Scattering panel.
3This module relies on guiframe manager.
4"""
5
6import wx
7import sys
8import os
9import numpy
10#import math
11import wx.aui as aui
12#import wx.lib.agw.aui as aui
13import logging
14import time
15
16import matplotlib
17matplotlib.interactive(False)
18#Use the WxAgg back end. The Wx one takes too long to render
19matplotlib.use('WXAgg')
20
21#from sas.guiframe.gui_manager import MDIFrame
22from sas.data_util.calcthread import CalcThread
23from sas.guiframe.local_perspectives.plotting.SimplePlot import PlotFrame
24from sas.guiframe.dataFitting import Data2D
25from sas.guiframe.dataFitting import Data1D
26from sas.dataloader.data_info import Detector
27from sas.dataloader.data_info import Source
28from sas.guiframe.panel_base import PanelBase
29from sas.guiframe.utils import format_number
30from sas.guiframe.events import StatusEvent
31from sas.calculator import sas_gen
32from sas.perspectives.calculator.calculator_widgets import OutputTextCtrl
33from sas.perspectives.calculator.calculator_widgets import InputTextCtrl
34from wx.lib.scrolledpanel import ScrolledPanel
35from sas.perspectives.calculator.load_thread import GenReader
36from sas.plottools.arrow3d import Arrow3D
37from sas.perspectives.calculator import calculator_widgets as widget
38from sas.guiframe.events import NewPlotEvent
39from sas.guiframe.documentation_window import DocumentationWindow
40
41_BOX_WIDTH = 76
42#Slit length panel size
43if sys.platform.count("win32") > 0:
44    PANEL_TOP = 0
45    PANEL_WIDTH = 570
46    PANEL_HEIGHT = 370
47    FONT_VARIANT = 0
48else:
49    PANEL_TOP = 40
50    PANEL_WIDTH = 620
51    PANEL_HEIGHT = 370
52    FONT_VARIANT = 1
53_QMAX_DEFAULT = 0.3
54_NPTS_DEFAULT = 50
55_Q1D_MIN = 0.001
56
57def add_icon(parent, frame):
58    """
59    Add icon in the frame
60    """
61    if parent != None:
62        if hasattr(frame, "IsIconized"):
63            if not frame.IsIconized():
64                try:
65                    icon = parent.GetIcon()
66                    frame.SetIcon(icon)
67                except:
68                    pass
69
70def _set_error(panel, item, show_msg=False):
71    """
72    Set_error dialog
73    """
74    if item != None:
75        item.SetBackgroundColour("pink")
76        item.Refresh()
77    if show_msg:
78        msg = "Error: wrong (or out of range) value entered."
79        if panel.parent.parent != None:
80            wx.PostEvent(panel.parent.parent,
81                     StatusEvent(status=msg, info='Error'))
82            panel.SetFocus()
83    return False
84
85
86
87class CalcGen(CalcThread):
88    """
89    Computation
90    """
91    def __init__(self,
92                 id= -1,
93                 input=None,
94                 completefn=None,
95                 updatefn=None,
96                 #elapsed = 0,
97                 yieldtime=0.01,
98                 worktime=0.01):
99        """
100        """
101        CalcThread.__init__(self, completefn,
102                 updatefn,
103                 yieldtime,
104                 worktime)
105        self.starttime = 0
106        self.id = id
107        self.input = input
108        self.update_fn = updatefn
109
110    def compute(self):
111        """
112        excuting computation
113        """
114        #elapsed = time.time() - self.starttime
115        self.starttime = time.time()
116        self.complete(input=self.input, update=self.update_fn)
117
118class SasGenPanel(ScrolledPanel, PanelBase):
119    """
120        Provides the sas gen calculator GUI.
121    """
122    ## Internal nickname for the window, used by the AUI manager
123    window_name = "Generic SAS Calculator"
124    ## Name to appear on the window title bar
125    window_caption = "Generic SAS "
126
127    def __init__(self, parent, *args, **kwds):
128        ScrolledPanel.__init__(self, parent, style=wx.RAISED_BORDER,
129                               *args, **kwds)
130        #kwds['style'] = wx.SUNKEN_BORDER
131        PanelBase.__init__(self)
132        #Font size
133        self.SetWindowVariant(variant=FONT_VARIANT)
134        self.SetupScrolling()
135        #thread to read data
136        self.reader = None
137        self.ext = None
138        self.id = 'GenSAS'
139        self.file_name = ''
140        self.time_text = None
141        self.orient_combo = None
142        self.omfreader = sas_gen.OMFReader()
143        self.sldreader = sas_gen.SLDReader()
144        self.pdbreader = sas_gen.PDBReader()
145        self.model = sas_gen.GenSAS()
146        self.param_dic = self.model.params
147        self.parameters = []
148        self.data = None
149        self.scale2d = None
150        self.is_avg = False
151        self.plot_frame = None
152        self.qmax_x = _QMAX_DEFAULT
153        self.npts_x = _NPTS_DEFAULT
154        self.sld_data = None
155        self.graph_num = 1
156        self.default_shape = 'rectangular'
157        # Object that receive status event
158        self.parent = parent
159        self._do_layout()
160        self._create_default_sld_data()
161        self._create_default_2d_data()
162        wx.CallAfter(self._set_sld_data_helper)
163
164    def _define_structure(self):
165        """
166            Define the main sizers building to build this application.
167        """
168        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
169        self.box_source = wx.StaticBox(self, -1, str("SLD Data File"))
170        self.box_parameters = wx.StaticBox(self, -1, str("Input Parameters"))
171        self.box_qrange = wx.StaticBox(self, -1, str("Q Range"))
172        self.boxsizer_source = wx.StaticBoxSizer(self.box_source,
173                                                    wx.VERTICAL)
174        self.boxsizer_parameters = wx.StaticBoxSizer(self.box_parameters,
175                                                    wx.VERTICAL)
176        self.boxsizer_qrange = wx.StaticBoxSizer(self.box_qrange,
177                                                    wx.VERTICAL)
178        self.data_name_sizer = wx.BoxSizer(wx.HORIZONTAL)
179        self.param_sizer = wx.BoxSizer(wx.HORIZONTAL)
180        self.shape_sizer = wx.BoxSizer(wx.HORIZONTAL)
181        self.hint_sizer = wx.BoxSizer(wx.HORIZONTAL)
182        self.qrange_sizer = wx.BoxSizer(wx.HORIZONTAL)
183        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
184
185    def _layout_data_name(self):
186        """
187            Fill the sizer containing data's name
188        """
189        data_name_txt = wx.StaticText(self, -1, 'Data: ')
190        self.data_name_tcl = OutputTextCtrl(self, -1,
191                                            size=(_BOX_WIDTH * 4, -1))
192        data_hint = "Loaded data"
193        self.data_name_tcl.SetToolTipString(data_hint)
194        #control that triggers importing data
195        id = wx.NewId()
196        self.browse_button = wx.Button(self, id, "Load")
197        hint_on_browse = "Click to load data into this panel."
198        self.browse_button.SetToolTipString(hint_on_browse)
199        self.Bind(wx.EVT_BUTTON, self.on_load_data, id=id)
200        self.data_name_sizer.AddMany([(data_name_txt, 0, wx.LEFT, 15),
201                                      (self.data_name_tcl, 0, wx.LEFT, 10),
202                                      (self.browse_button, 0, wx.LEFT, 10)])
203    def _layout_param_size(self):
204        """
205            Fill the sizer containing slit size information
206        """
207        self.parameters = []
208        sizer = wx.GridBagSizer(3, 6)
209        model = self.model
210        details = self.model.details
211        params = self.model.params
212        ix = 0
213        iy = 0
214        param_title = wx.StaticText(self, -1, 'Parameter')
215        sizer.Add(param_title, (iy, ix), (1, 1), \
216                            wx.EXPAND | wx.ADJUST_MINSIZE, 0)
217        ix += 1
218        value_title = wx.StaticText(self, -1, 'Value')
219        sizer.Add(value_title, (iy, ix), (1, 1), \
220                            wx.EXPAND | wx.ADJUST_MINSIZE, 0)
221        ix += 1
222        unit_title = wx.StaticText(self, -1, 'Unit')
223        sizer.Add(unit_title, (iy, ix), (1, 1), \
224                            wx.EXPAND | wx.ADJUST_MINSIZE, 0)
225        key_list = params.keys()
226        key_list.sort()
227        for param in key_list:
228            iy += 1
229            ix = 0
230            p_name = wx.StaticText(self, -1, param)
231            sizer.Add(p_name, (iy, ix), (1, 1), \
232                            wx.EXPAND | wx.ADJUST_MINSIZE, 0)
233            ## add parameter value
234            ix += 1
235            value = model.getParam(param)
236            ctl = InputTextCtrl(self, -1, size=(_BOX_WIDTH * 2, 20),
237                                style=wx.TE_PROCESS_ENTER)
238            #ctl.SetToolTipString(\
239            #            "Hit 'Enter' after typing to update the plot.")
240            ctl.SetValue(format_number(value, True))
241            sizer.Add(ctl, (iy, ix), (1, 1), wx.EXPAND)
242            ## add unit
243            ix += 1
244            unit = wx.StaticText(self, -1, details[param][0])
245            sizer.Add(unit, (iy, ix), (1, 1), \
246                            wx.EXPAND | wx.ADJUST_MINSIZE, 0)
247            self.parameters.append([p_name, ctl, unit])
248
249        self.param_sizer.Add(sizer, 0, wx.LEFT, 10)
250
251    def _layout_hint(self):
252        """
253            Fill the sizer containing hint
254        """
255        hint_msg = "We support omf, sld or pdb data files only."
256        hint_msg += "         "
257        if FONT_VARIANT < 1:
258            hint_msg += "Very "
259        hint_msg += "SLOW drawing -->"
260        hint_txt = wx.StaticText(self, -1, hint_msg)
261
262        id = wx.NewId()
263        self.draw_button = wx.Button(self, id, "Arrow Draw")
264        hint_on_draw = "Draw with arrows. Caution: it is a very slow drawing."
265        self.draw_button.SetToolTipString(hint_on_draw)
266        self.draw_button.Bind(wx.EVT_BUTTON, self.sld_draw, id=id)
267
268        self.draw_button.Enable(False)
269        self.hint_sizer.AddMany([(hint_txt, 0, wx.LEFT, 15),
270                                 (self.draw_button, 0, wx.LEFT, 7)])
271
272    def _layout_shape(self):
273        """
274        Fill the shape sizer
275        """
276        label_txt = wx.StaticText(self, -1, "Shape:")
277        self.shape_combo = self._fill_shape_combo()
278        self.shape_sizer.AddMany([(label_txt, 0, wx.LEFT, 15),
279                                (self.shape_combo, 0, wx.LEFT, 5)])
280
281    def _fill_shape_combo(self):
282        """
283        Fill up the shape combo box
284        """
285        shape_combo = wx.ComboBox(self, -1, size=(150, -1),
286                                      style=wx.CB_READONLY)
287        shape_combo.Append('Rectangular')
288        shape_combo.Append('Ellipsoid')
289        shape_combo.Bind(wx.EVT_COMBOBOX, self._on_shape_select)
290        shape_combo.SetSelection(0)
291        return shape_combo
292
293    def _on_shape_select(self, event):
294        """
295        On selecting a shape
296        """
297        event.Skip()
298        label = event.GetEventObject().GetValue().lower()
299        self.default_shape = label
300        self.parent.set_omfpanel_default_shap(self.default_shape)
301        self.parent.set_omfpanel_npts()
302
303    def _fill_orient_combo(self):
304        """
305        Fill up the orientation combo box: used only for atomic structure
306        """
307        orient_combo = wx.ComboBox(self, -1, size=(150, -1),
308                                      style=wx.CB_READONLY)
309        orient_combo.Append('Fixed orientation')
310        orient_combo.Append('Debye full avg.')
311        #orient_combo.Append('Debye sph. sym.')
312
313        orient_combo.Bind(wx.EVT_COMBOBOX, self._on_orient_select)
314        orient_combo.SetSelection(0)
315        return orient_combo
316
317    def _on_orient_select(self, event):
318        """
319        On selecting a orientation
320        """
321        event.Skip()
322        cb = event.GetEventObject()
323        if cb.GetCurrentSelection() == 2:
324            self.is_avg = None
325        else:
326            is_avg = cb.GetCurrentSelection() == 1
327            self.is_avg = is_avg
328        self.model.set_is_avg(self.is_avg)
329        self.set_est_time()
330
331    def _layout_qrange(self):
332        """
333        Fill the sizer containing qrange
334        """
335        sizer = wx.GridBagSizer(2, 3)
336        ix = 0
337        iy = 0
338        #key_list.sort()
339        name = wx.StaticText(self, -1, 'No. of Qx (Qy) bins: ')
340        sizer.Add(name, (iy, ix), (1, 1), \
341                        wx.EXPAND | wx.ADJUST_MINSIZE, 0)
342        ## add parameter value
343        ix += 1
344        self.npt_ctl = InputTextCtrl(self, -1, size=(_BOX_WIDTH * 1.5, 20),
345                            style=wx.TE_PROCESS_ENTER)
346        self.npt_ctl.Bind(wx.EVT_TEXT, self._onparamEnter)
347        self.npt_ctl.SetValue(format_number(self.npts_x, True))
348        sizer.Add(self.npt_ctl, (iy, ix), (1, 1), wx.EXPAND)
349        ## add unit
350        ix += 1
351        unit = wx.StaticText(self, -1, '')
352        sizer.Add(unit, (iy, ix), (1, 1), \
353                        wx.EXPAND | wx.ADJUST_MINSIZE, 0)
354        iy += 1
355        ix = 0
356        name = wx.StaticText(self, -1, 'Qx (Qy) Max: ')
357        sizer.Add(name, (iy, ix), (1, 1), \
358                        wx.EXPAND | wx.ADJUST_MINSIZE, 0)
359        ## add parameter value
360        ix += 1
361        self.qmax_ctl = InputTextCtrl(self, -1, size=(_BOX_WIDTH * 1.5, 20),
362                            style=wx.TE_PROCESS_ENTER)
363        self.qmax_ctl.Bind(wx.EVT_TEXT, self._onparamEnter)
364        self.qmax_ctl.SetValue(format_number(self.qmax_x, True))
365        sizer.Add(self.qmax_ctl, (iy, ix), (1, 1), wx.EXPAND)
366        ## add unit
367        ix += 1
368        unit = wx.StaticText(self, -1, '[1/A]')
369        sizer.Add(unit, (iy, ix), (1, 1), \
370                        wx.EXPAND | wx.ADJUST_MINSIZE, 0)
371        self.qrange_sizer.Add(sizer, 0, wx.LEFT, 10)
372
373    def _layout_button(self):
374        """
375            Do the layout for the button widgets
376        """
377        self.est_time = '*Estimated Computation time :\n  %s'
378        self.time_text = wx.StaticText(self, -1, self.est_time % str('2 sec'))
379        self.orient_combo = self._fill_orient_combo()
380        self.orient_combo.Show(False)
381        self.bt_compute = wx.Button(self, wx.NewId(), 'Compute')
382        self.bt_compute.Bind(wx.EVT_BUTTON, self.on_compute)
383        self.bt_compute.SetToolTipString("Compute 2D Scattering Pattern.")
384        self.bt_help = wx.Button(self, wx.NewId(), 'HELP')
385        self.bt_help.Bind(wx.EVT_BUTTON, self.on_help)
386        self.bt_help.SetToolTipString("Help on Scatter Calculator")
387        self.button_sizer.AddMany([(self.time_text , 0, wx.LEFT, 20),
388                                   (self.orient_combo , 0, wx.LEFT, 20),
389                                   (self.bt_compute, 0, wx.LEFT, 20),
390                                   (self.bt_help, 0, wx.LEFT, 5)])
391
392    def estimate_ctime(self):
393        """
394        Calculation time estimation
395        """
396        # magic equation: not very accurate
397        factor = 1
398        n_qbins = float(self.npt_ctl.GetValue())
399        n_qbins *= n_qbins
400        n_pixs = float(self.parent.get_npix())
401        if self.is_avg:
402            factor = 6
403            n_pixs *= (n_pixs / 200)
404        x_in = n_qbins * n_pixs / 100000
405        etime = factor + 0.085973 * x_in
406        return int(etime)
407
408    def set_est_time(self):
409        """
410        Set text for est. computation time
411        """
412        unit = 'sec'
413        if self.time_text != None:
414            self.time_text.SetForegroundColour('black')
415            etime = self.estimate_ctime()
416            if etime > 60:
417                etime /= 60
418                unit = 'min'
419                self.time_text.SetForegroundColour('red')
420            time_str = str(etime) + ' ' + unit
421            self.time_text.SetLabel(self.est_time % time_str)
422
423    def _do_layout(self):
424        """
425        Draw window content
426        """
427        self._define_structure()
428        self._layout_data_name()
429        self._layout_param_size()
430        self._layout_qrange()
431        self._layout_hint()
432        self._layout_shape()
433        self._layout_button()
434        self.boxsizer_source.AddMany([(self.data_name_sizer, 0,
435                                        wx.EXPAND | wx.TOP | wx.BOTTOM, 5),
436                                      (self.hint_sizer, 0,
437                                        wx.EXPAND | wx.TOP | wx.BOTTOM, 5),
438                                      (self.shape_sizer, 0,
439                                        wx.EXPAND | wx.TOP | wx.BOTTOM, 5)])
440        self.boxsizer_parameters.AddMany([(self.param_sizer, 0,
441                                     wx.EXPAND | wx.TOP | wx.BOTTOM, 5), ])
442        self.boxsizer_qrange.AddMany([(self.qrange_sizer, 0,
443                                     wx.EXPAND | wx.TOP | wx.BOTTOM, 5), ])
444        self.main_sizer.AddMany([(self.boxsizer_source, 0,
445                                  wx.EXPAND | wx.ALL, 10),
446                                 (self.boxsizer_parameters, 0,
447                                  wx.EXPAND | wx.ALL, 10),
448                                 (self.boxsizer_qrange, 0,
449                                  wx.EXPAND | wx.ALL, 10),
450                                 (self.button_sizer, 0,
451                                  wx.EXPAND | wx.TOP | wx.BOTTOM, 5)])
452        self.SetSizer(self.main_sizer)
453        self.SetAutoLayout(True)
454
455    def _create_default_sld_data(self):
456        """
457        Making default sld-data
458        """
459        sld_n_default = 6.97e-06
460        omfdata = sas_gen.OMFData()
461        omf2sld = sas_gen.OMF2SLD()
462        omf2sld.set_data(omfdata, self.default_shape)
463        self.sld_data = omf2sld.output
464        self.sld_data.is_data = False
465        self.sld_data.filename = "Default SLD Profile"
466        self.sld_data.set_sldn(sld_n_default)
467        self.data_name_tcl.SetValue(self.sld_data.filename)
468
469    def choose_data_file(self, location=None):
470        """
471        Choosing a dtata file
472        """
473        path = None
474        filename = ''
475        if location == None:
476            location = os.getcwd()
477
478        exts = "*" + self.omfreader.ext[0]
479        exts += ", *" + self.sldreader.ext[0]
480        exts += ", *" + self.pdbreader.ext[0]
481        all_type = "All GEN files (%s, %s) | %s" % (exts.upper(), exts.lower(),
482                                               exts.lower().replace(',', ';'))
483        wildcard = [all_type]
484        omf_type = self.omfreader.type
485        sld_type = self.sldreader.type
486        pdb_type = self.pdbreader.type
487
488        for type in sld_type:
489            wildcard.append(type)
490        for type in omf_type:
491            wildcard.append(type)
492        for type in pdb_type:
493            wildcard.append(type)
494        wildcard = '|'.join(wildcard)
495        dlg = wx.FileDialog(self, "Choose a file", location,
496                            "", wildcard, wx.OPEN)
497        if dlg.ShowModal() == wx.ID_OK:
498            path = dlg.GetPath()
499            filename = os.path.basename(path)
500        dlg.Destroy()
501        return path
502
503    def on_load_data(self, event):
504        """
505        Open a file dialog to allow the user to select a given file.
506        The user is only allow to load file with extension .omf, .txt, .sld.
507        Display the slit size corresponding to the loaded data.
508        """
509        location = self.parent.get_path()
510        path = self.choose_data_file(location=location)
511        if path is None:
512            return
513
514        self.shape_sizer.ShowItems(False)
515        self.default_shape = 'rectangular'
516        self.parent.set_omfpanel_default_shap(self.default_shape)
517
518        self.parent.set_file_location(os.path.dirname(path))
519        try:
520            #Load data
521            self.ext = os.path.splitext(path)[-1]
522            if self.ext in self.omfreader.ext:
523                loader = self.omfreader
524            elif self.ext in self.sldreader.ext:
525                loader = self.sldreader
526            elif self.ext in self.pdbreader.ext:
527                loader = self.pdbreader
528            else:
529                loader = None
530            if self.reader is not None and self.reader.isrunning():
531                self.reader.stop()
532            self.browse_button.Enable(False)
533            self.browse_button.SetLabel("Loading...")
534            if self.parent.parent is not None:
535                wx.PostEvent(self.parent.parent,
536                                StatusEvent(status="Loading...",
537                                type="progress"))
538            self.reader = GenReader(path=path, loader=loader,
539                                    completefn=self.complete_loading,
540                                    updatefn=self.load_update)
541            self.reader.queue()
542            #self.load_update()
543        except:
544            self.ext = None
545            if self.parent.parent is None:
546                return
547            msg = "Generic SAS Calculator: %s" % (sys.exc_value)
548            wx.PostEvent(self.parent.parent,
549                          StatusEvent(status=msg, type='stop'))
550            self.SetFocus()
551            return
552
553    def load_update(self):
554        """
555        print update on the status bar
556        """
557        if self.parent.parent is None:
558                return
559        if self.reader.isrunning():
560            type = "progress"
561        else:
562            type = "stop"
563        wx.PostEvent(self.parent.parent, StatusEvent(status="",
564                                                  type=type))
565
566    def complete_loading(self, data=None, filename=''):
567        """
568        Complete the loading
569        """
570        #compute the slit size
571        self.browse_button.Enable(True)
572        self.browse_button.SetLabel('Load')
573        try:
574            is_pdbdata = False
575            filename = data.filename
576            self.data_name_tcl.SetValue(str(filename))
577            self.file_name = filename.split('.')[0]
578            self.orient_combo.SetSelection(0)
579            self.is_avg = False
580            if self.ext in self.omfreader.ext:
581                gen = sas_gen.OMF2SLD()
582                gen.set_data(data)
583                #omf_data = data
584                self.sld_data = gen.get_magsld()
585            elif self.ext in self.sldreader.ext:
586                self.sld_data = data
587            elif self.ext in self.pdbreader.ext:
588                self.sld_data = data
589                is_pdbdata = True
590                #omf_data = None
591            else:
592                raise
593            self.orient_combo.Show(is_pdbdata)
594            self.button_sizer.Layout()
595            self._set_sld_data_helper(True)
596        except:
597            if self.parent.parent is None:
598                raise
599            msg = "Loading Error: This file format is not supported "
600            msg += "for GenSAS."
601            wx.PostEvent(self.parent.parent,
602                          StatusEvent(status=msg, type='stop', info='Error'))
603            self.SetFocus()
604            return
605        if self.parent.parent is None:
606            return
607
608        msg = "Load Complete"
609        wx.PostEvent(self.parent.parent, StatusEvent(status=msg, type='stop'))
610        self.SetFocus()
611
612    def _set_sld_data_helper(self, is_draw=False):
613        """
614        Set sld data helper
615        """
616        #is_avg = self.orient_combo.GetCurrentSelection() == 1
617        self.model.set_is_avg(self.is_avg)
618        self.model.set_sld_data(self.sld_data)
619
620        self.draw_button.Enable(self.sld_data != None)
621        wx.CallAfter(self.parent.set_sld_data, self.sld_data)
622        self._update_model_params()
623        if is_draw:
624            wx.CallAfter(self.sld_draw, None, False)
625
626    def _update_model_params(self):
627        """
628        Update the model parameter values
629        """
630        for list in self.parameters:
631            param_name = list[0].GetLabelText()
632            val = str(self.model.params[param_name])
633            list[1].SetValue(val)
634
635    def set_volume_ctl_val(self, val):
636        """
637        Set volume txtctrl value
638        """
639        for list in self.parameters:
640            param_name = list[0].GetLabelText()
641            if param_name.lower() == 'total_volume':
642                list[1].SetValue(val)
643                list[1].Refresh()
644                break
645
646    def _onparamEnter(self, event):
647        """
648        On param enter
649        """
650        try:
651            item = event.GetEventObject()
652            self._check_value()
653            item.Refresh()
654        except:
655            pass
656
657    def sld_draw(self, event=None, has_arrow=True):
658        """
659        Draw 3D sld profile
660        """
661        flag = self.parent.check_omfpanel_inputs()
662        if not flag:
663            infor = 'Error'
664            msg = 'Error: Wrong inputs in the SLD info panel.'
665            # inform msg to wx
666            wx.PostEvent(self.parent.parent,
667                    StatusEvent(status=msg, info=infor))
668            self.SetFocus()
669            return
670
671        self.sld_data = self.parent.get_sld_from_omf()
672        output = self.sld_data
673        #frame_size = wx.Size(470, 470)   
674        self.plot_frame = PlotFrame(self, -1, 'testView')
675        frame = self.plot_frame
676        frame.Show(False)
677        add_icon(self.parent, frame)
678        panel = frame.plotpanel
679        try:
680            # mpl >= 1.0.0
681            ax = panel.figure.gca(projection='3d')
682        except:
683            # mpl < 1.0.0
684            try:
685                from mpl_toolkits.mplot3d import Axes3D
686                ax = Axes3D(panel.figure)
687            except:
688                logging.error("PlotPanel could not import Axes3D")
689                raise
690        panel.dimension = 3
691        graph_title = self._sld_plot_helper(ax, output, has_arrow)
692        # Use y, z axes (in mpl 3d) as z, y axes
693        # that consistent with our SAS detector coords.
694        ax.set_xlabel('x ($\A%s$)' % output.pos_unit)
695        ax.set_ylabel('z ($\A%s$)' % output.pos_unit)
696        ax.set_zlabel('y ($\A%s$)' % output.pos_unit)
697        panel.subplot.figure.subplots_adjust(left=0.05, right=0.95,
698                                             bottom=0.05, top=0.96)
699        if output.pix_type == 'atom':
700            ax.legend(loc='upper left', prop={'size':10})
701        num_graph = str(self.graph_num)
702        frame.SetTitle('Graph %s: %s' % (num_graph, graph_title))
703        wx.CallAfter(frame.Show, True)
704        self.graph_num += 1
705
706    def _sld_plot_helper(self, ax, output, has_arrow=False):
707        """
708        Actual plot definition happens here
709        :Param ax: axis3d
710        :Param output: sld_data [MagSLD]
711        :Param has_arrow: whether or not draws M vector [bool]
712        """
713        # Set the locals
714        color_dic = {'H':'blue', 'D':'purple', 'N': 'orange',
715                     'O':'red', 'C':'green', 'P':'cyan', 'Other':'k'}
716        marker = ','
717        m_size = 2
718        graph_title = self.file_name
719        graph_title += "   3D SLD Profile "
720        pos_x = output.pos_x
721        pos_y = output.pos_y
722        pos_z = output.pos_z
723        sld_mx = output.sld_mx
724        sld_my = output.sld_my
725        sld_mz = output.sld_mz
726        pix_symbol = output.pix_symbol
727        if output.pix_type == 'atom':
728            marker = 'o'
729            m_size = 3.5
730        sld_tot = (numpy.fabs(sld_mx) + numpy.fabs(sld_my) + \
731                   numpy.fabs(sld_mz) + numpy.fabs(output.sld_n))
732        is_nonzero = sld_tot > 0.0
733        is_zero = sld_tot == 0.0
734        # I. Plot null points
735        if is_zero.any():
736            ax.plot(pos_x[is_zero], pos_z[is_zero], pos_y[is_zero], marker,
737                    c="y", alpha=0.5, markeredgecolor='y', markersize=m_size)
738            pos_x = pos_x[is_nonzero]
739            pos_y = pos_y[is_nonzero]
740            pos_z = pos_z[is_nonzero]
741            sld_mx = sld_mx[is_nonzero]
742            sld_my = sld_my[is_nonzero]
743            sld_mz = sld_mz[is_nonzero]
744            pix_symbol = output.pix_symbol[is_nonzero]
745        # II. Plot selective points in color
746        other_color = numpy.ones(len(pix_symbol), dtype='bool')
747        for key in color_dic.keys():
748            chosen_color = pix_symbol == key
749            if numpy.any(chosen_color):
750                other_color = other_color & (chosen_color != True)
751                color = color_dic[key]
752                ax.plot(pos_x[chosen_color], pos_z[chosen_color],
753                        pos_y[chosen_color], marker, c=color, alpha=0.5,
754                        markeredgecolor=color, markersize=m_size, label=key)
755        # III. Plot All others       
756        if numpy.any(other_color):
757            a_name = ''
758            if output.pix_type == 'atom':
759                # Get atom names not in the list
760                a_names = [symb  for symb in pix_symbol \
761                           if symb not in color_dic.keys()]
762                a_name = a_names[0]
763                for name in a_names:
764                    new_name = ", " + name
765                    if a_name.count(name) == 0:
766                        a_name += new_name
767            # plot in black
768            ax.plot(pos_x[other_color], pos_z[other_color], pos_y[other_color],
769                    marker, c="k", alpha=0.5, markeredgecolor="k",
770                    markersize=m_size, label=a_name)
771        # IV. Draws atomic bond with grey lines if any
772        if output.has_conect:
773            for ind in range(len(output.line_x)):
774                ax.plot(output.line_x[ind], output.line_z[ind],
775                        output.line_y[ind], '-', lw=0.6, c="grey", alpha=0.3)
776        # V. Draws magnetic vectors
777        if has_arrow and len(pos_x) > 0:
778            graph_title += " - Magnetic Vector as Arrow -"
779            panel = self.plot_frame.plotpanel
780            def _draw_arrow(input=None, update=None):
781                """
782                draw magnetic vectors w/arrow
783                """
784                max_mx = max(numpy.fabs(sld_mx))
785                max_my = max(numpy.fabs(sld_my))
786                max_mz = max(numpy.fabs(sld_mz))
787                max_m = max(max_mx, max_my, max_mz)
788                try:
789                    max_step = max(output.xstepsize, output.ystepsize,
790                                   output.zstepsize)
791                except:
792                    max_step = 0
793                if max_step <= 0:
794                    max_step = 5
795                try:
796                    if max_m != 0:
797                        unit_x2 = sld_mx / max_m
798                        unit_y2 = sld_my / max_m
799                        unit_z2 = sld_mz / max_m
800                        # 0.8 is for avoiding the color becomes white=(1,1,1))
801                        color_x = numpy.fabs(unit_x2 * 0.8)
802                        color_y = numpy.fabs(unit_y2 * 0.8)
803                        color_z = numpy.fabs(unit_z2 * 0.8)
804                        x2 = pos_x + unit_x2 * max_step
805                        y2 = pos_y + unit_y2 * max_step
806                        z2 = pos_z + unit_z2 * max_step
807                        x_arrow = numpy.column_stack((pos_x, x2))
808                        y_arrow = numpy.column_stack((pos_y, y2))
809                        z_arrow = numpy.column_stack((pos_z, z2))
810                        colors = numpy.column_stack((color_x, color_y, color_z))
811                        arrows = Arrow3D(panel, x_arrow, z_arrow, y_arrow,
812                                        colors, mutation_scale=10, lw=1,
813                                        arrowstyle="->", alpha=0.5)
814                        ax.add_artist(arrows)
815                except:
816                    pass
817                msg = "Arrow Drawing completed.\n"
818                status_type = 'stop'
819                self._status_info(msg, status_type)
820            msg = "Arrow Drawing is in progress..."
821            status_type = 'progress'
822            self._status_info(msg, status_type)
823            draw_out = CalcGen(input=ax,
824                             completefn=_draw_arrow, updatefn=self._update)
825            draw_out.queue()
826        return graph_title
827
828    def set_input_params(self):
829        """
830        Set model parameters
831        """
832        for list in self.parameters:
833            param_name = list[0].GetLabelText()
834            param_value = float(list[1].GetValue())
835            self.model.setParam(param_name, param_value)
836
837    def on_compute(self, event):
838        """
839        Compute I(qx, qy)
840        """
841        flag = self.parent.check_omfpanel_inputs()
842        if not flag and self.parent.parent != None:
843            infor = 'Error'
844            msg = 'Error: Wrong inputs in the SLD info panel.'
845            # inform msg to wx
846            wx.PostEvent(self.parent.parent,
847                    StatusEvent(status=msg, info=infor))
848            self.SetFocus()
849            return
850        self.sld_data = self.parent.get_sld_from_omf()
851        if self.sld_data == None:
852            if self.parent.parent != None:
853                infor = 'Error'
854                msg = 'Error: No data has been selected.'
855                # inform msg to wx
856                wx.PostEvent(self.parent.parent,
857                        StatusEvent(status=msg, info=infor))
858                self.SetFocus()
859            return
860        flag = self._check_value()
861        if not flag:
862            _set_error(self, None, True)
863            return
864        try:
865            self.model.set_sld_data(self.sld_data)
866            self.set_input_params()
867            if self.is_avg or self.is_avg == None:
868                self._create_default_1d_data()
869                i_out = numpy.zeros(len(self.data.y))
870                inputs = [self.data.x, [], i_out]
871            else:
872                self._create_default_2d_data()
873                i_out = numpy.zeros(len(self.data.data))
874                inputs = [self.data.qx_data, self.data.qy_data, i_out]
875
876            msg = "Computation is in progress..."
877            status_type = 'progress'
878            self._status_info(msg, status_type)
879            cal_out = CalcGen(input=inputs,
880                              completefn=self.complete,
881                              updatefn=self._update)
882            cal_out.queue()
883
884        except:
885            msg = "%s." % sys.exc_value
886            status_type = 'stop'
887            self._status_info(msg, status_type)
888            wx.PostEvent(self.parent.parent,
889                        StatusEvent(status=msg, info='Error'))
890            self.SetFocus()
891
892    def on_help(self, event):
893        """
894        Bring up the General scattering Calculator Documentation whenever
895        the HELP button is clicked.
896
897        Calls DocumentationWindow with the path of the location within the
898        documentation tree (after /doc/ ....".  Note that when using old
899        versions of Wx (before 2.9) and thus not the release version of
900        installers, the help comes up at the top level of the file as
901        webbrowser does not pass anything past the # to the browser when it is
902        running "file:///...."
903
904    :param evt: Triggers on clicking the help button
905    """
906
907        _TreeLocation = "user/perspectives/calculator/sas_calculator_help.html"
908        _doc_viewer = DocumentationWindow(self, -1, \
909             _TreeLocation, "General Scattering Calculator Help")
910
911    def _check_value(self):
912        """
913        Check input values if float
914        """
915        flag = True
916        self.npt_ctl.SetBackgroundColour("white")
917        self.qmax_ctl.SetBackgroundColour("white")
918        try:
919            npt_val = float(self.npt_ctl.GetValue())
920            if npt_val < 2 or npt_val > 1000:
921                raise
922            self.npt_ctl.SetValue(str(int(npt_val)))
923            self.set_est_time()
924        except:
925            flag = _set_error(self, self.npt_ctl)
926        try:
927            qmax_val = float(self.qmax_ctl.GetValue())
928            if qmax_val <= 0 or qmax_val > 1000:
929                raise
930        except:
931            flag = _set_error(self, self.qmax_ctl)
932        for list in self.parameters:
933            list[1].SetBackgroundColour("white")
934            param_name = list[0].GetLabelText()
935            try:
936                param_val = float(list[1].GetValue())
937                if param_name.count('frac') > 0:
938                    if param_val < 0 or param_val > 1:
939                       raise
940            except:
941                flag = _set_error(self, list[1])
942        return flag
943
944    def _status_info(self, msg='', type="update"):
945        """
946        Status msg
947        """
948        if type == "stop":
949            label = "Compute"
950            able = True
951        else:
952            label = "Wait..."
953            able = False
954        self.bt_compute.Enable(able)
955        self.bt_compute.SetLabel(label)
956        self.bt_compute.SetToolTipString(label)
957        if self.parent.parent != None:
958            wx.PostEvent(self.parent.parent,
959                             StatusEvent(status=msg, type=type))
960
961    def _update(self, time=None):
962        """
963        Update the progress bar
964        """
965        if self.parent.parent == None:
966            return
967        type = "progress"
968        msg = "Please wait. Computing... (Note: Window may look frozen.)"
969        wx.PostEvent(self.parent.parent, StatusEvent(status=msg,
970                                                  type=type))
971
972    def complete(self, input, update=None):
973        """
974        Gen compute complete function
975        :Param input: input list [qx_data, qy_data, i_out]
976        """
977        out = numpy.empty(0)
978        #s = time.time()
979        for ind in range(len(input[0])):
980            if self.is_avg:
981                if ind % 1 == 0 and update != None:
982                    update()
983                    time.sleep(0.1)
984                inputi = [input[0][ind:ind + 1], [], input[2][ind:ind + 1]]
985                outi = self.model.run(inputi)
986                out = numpy.append(out, outi)
987            else:
988                if ind % 50 == 0  and update != None:
989                    update()
990                    time.sleep(0.001)
991                inputi = [input[0][ind:ind + 1], input[1][ind:ind + 1],
992                          input[2][ind:ind + 1]]
993                outi = self.model.runXY(inputi)
994                out = numpy.append(out, outi)
995        #print time.time() - s
996        if self.is_avg or self.is_avg == None:
997            self._draw1D(out)
998        else:
999            #out = self.model.runXY(input)
1000            self._draw2D(out)
1001
1002        msg = "Gen computation completed.\n"
1003        status_type = 'stop'
1004        self._status_info(msg, status_type)
1005
1006    def _create_default_2d_data(self):
1007        """
1008        Create 2D data by default
1009        Only when the page is on theory mode.
1010        :warning: This data is never plotted.
1011        """
1012        self.qmax_x = float(self.qmax_ctl.GetValue())
1013        self.npts_x = int(float(self.npt_ctl.GetValue()))
1014        self.data = Data2D()
1015        qmax = self.qmax_x #/ numpy.sqrt(2)
1016        self.data.xaxis('\\rm{Q_{x}}', '\AA^{-1}')
1017        self.data.yaxis('\\rm{Q_{y}}', '\AA^{-1}')
1018        self.data.is_data = False
1019        self.data.id = str(self.uid) + " GenData"
1020        self.data.group_id = str(self.uid) + " Model2D"
1021        ## Default values
1022        self.data.detector.append(Detector())
1023        index = len(self.data.detector) - 1
1024        self.data.detector[index].distance = 8000   # mm
1025        self.data.source.wavelength = 6             # A
1026        self.data.detector[index].pixel_size.x = 5  # mm
1027        self.data.detector[index].pixel_size.y = 5  # mm
1028        self.data.detector[index].beam_center.x = qmax
1029        self.data.detector[index].beam_center.y = qmax
1030        xmax = qmax
1031        xmin = -qmax
1032        ymax = qmax
1033        ymin = -qmax
1034        qstep = self.npts_x
1035
1036        x = numpy.linspace(start=xmin, stop=xmax, num=qstep, endpoint=True)
1037        y = numpy.linspace(start=ymin, stop=ymax, num=qstep, endpoint=True)
1038        ## use data info instead
1039        new_x = numpy.tile(x, (len(y), 1))
1040        new_y = numpy.tile(y, (len(x), 1))
1041        new_y = new_y.swapaxes(0, 1)
1042        # all data reuire now in 1d array
1043        qx_data = new_x.flatten()
1044        qy_data = new_y.flatten()
1045        q_data = numpy.sqrt(qx_data * qx_data + qy_data * qy_data)
1046        # set all True (standing for unmasked) as default
1047        mask = numpy.ones(len(qx_data), dtype=bool)
1048        # store x and y bin centers in q space
1049        x_bins = x
1050        y_bins = y
1051        self.data.source = Source()
1052        self.data.data = numpy.ones(len(mask))
1053        self.data.err_data = numpy.ones(len(mask))
1054        self.data.qx_data = qx_data
1055        self.data.qy_data = qy_data
1056        self.data.q_data = q_data
1057        self.data.mask = mask
1058        self.data.x_bins = x_bins
1059        self.data.y_bins = y_bins
1060        # max and min taking account of the bin sizes
1061        self.data.xmin = xmin
1062        self.data.xmax = xmax
1063        self.data.ymin = ymin
1064        self.data.ymax = ymax
1065
1066    def _create_default_1d_data(self):
1067        """
1068        Create 2D data by default
1069        Only when the page is on theory mode.
1070        :warning: This data is never plotted.
1071                    residuals.x = data_copy.x[index]
1072            residuals.dy = numpy.ones(len(residuals.y))
1073            residuals.dx = None
1074            residuals.dxl = None
1075            residuals.dxw = None
1076        """
1077        self.qmax_x = float(self.qmax_ctl.GetValue())
1078        self.npts_x = int(float(self.npt_ctl.GetValue()))
1079        qmax = self.qmax_x #/ numpy.sqrt(2)
1080        ## Default values
1081        xmax = qmax
1082        xmin = qmax * _Q1D_MIN
1083        qstep = self.npts_x
1084        x = numpy.linspace(start=xmin, stop=xmax, num=qstep, endpoint=True)
1085        # store x and y bin centers in q space
1086        #self.data.source = Source()
1087        y = numpy.ones(len(x))
1088        dy = numpy.zeros(len(x))
1089        dx = numpy.zeros(len(x))
1090        self.data = Data1D(x=x, y=y)
1091        self.data.dx = dx
1092        self.data.dy = dy
1093
1094    def _draw1D(self, y_out):
1095        """
1096        Complete get the result of modelthread and create model 2D
1097        that can be plot.
1098        """
1099        page_id = self.id
1100        data = self.data
1101
1102        model = self.model
1103        state = None
1104
1105        new_plot = Data1D(x=data.x, y=y_out)
1106        new_plot.dx = data.dx
1107        new_plot.dy = data.dy
1108        new_plot.xaxis('\\rm{Q_{x}}', '\AA^{-1}')
1109        new_plot.yaxis('\\rm{Intensity}', 'cm^{-1}')
1110        new_plot.is_data = False
1111        new_plot.id = str(self.uid) + " GenData1D"
1112        new_plot.group_id = str(self.uid) + " Model1D"
1113        new_plot.name = model.name + '1d'
1114        new_plot.title = "Generic model1D "
1115        new_plot.id = str(page_id) + ': ' + self.file_name \
1116                        + ' #%s' % str(self.graph_num) + "_1D"
1117        new_plot.group_id = str(page_id) + " Model1D" + \
1118                             ' #%s' % str(self.graph_num) + "_1D"
1119        new_plot.is_data = False
1120
1121        title = new_plot.title
1122        _yaxis, _yunit = new_plot.get_yaxis()
1123        _xaxis, _xunit = new_plot.get_xaxis()
1124        new_plot.xaxis(str(_xaxis), str(_xunit))
1125        new_plot.yaxis(str(_yaxis), str(_yunit))
1126
1127        if new_plot.is_data:
1128            data_name = str(new_plot.name)
1129        else:
1130            data_name = str(model.__class__.__name__) + '1d'
1131
1132        if len(title) > 1:
1133            new_plot.title = "Gen Theory for %s " % model.name + data_name
1134        new_plot.name = new_plot.id
1135        new_plot.label = new_plot.id
1136        #theory_data = deepcopy(new_plot)
1137        if self.parent.parent != None:
1138            self.parent.parent.update_theory(data_id=new_plot.id,
1139                                           theory=new_plot,
1140                                           state=state)
1141        title = new_plot.title
1142        num_graph = str(self.graph_num)
1143        wx.CallAfter(self.parent.draw_graph, new_plot,
1144                     title="GEN Graph %s: " % num_graph + new_plot.id)
1145        self.graph_num += 1
1146
1147    def _draw2D(self, image):
1148        """
1149        Complete get the result of modelthread and create model 2D
1150        that can be plot.
1151        """
1152        page_id = self.id
1153        data = self.data
1154
1155        model = self.model
1156        qmin = 0.0
1157        state = None
1158
1159        numpy.nan_to_num(image)
1160        new_plot = Data2D(image=image, err_image=data.err_data)
1161        new_plot.name = model.name + '2d'
1162        new_plot.title = "Generic model 2D "
1163        new_plot.id = str(page_id) + ': ' + self.file_name \
1164                        + ' #%s' % str(self.graph_num) + "_2D"
1165        new_plot.group_id = str(page_id) + " Model2D" \
1166                        + ' #%s' % str(self.graph_num) + "_2D"
1167        new_plot.detector = data.detector
1168        new_plot.source = data.source
1169        new_plot.is_data = False
1170        new_plot.qx_data = data.qx_data
1171        new_plot.qy_data = data.qy_data
1172        new_plot.q_data = data.q_data
1173        new_plot.mask = data.mask
1174        ## plot boundaries
1175        new_plot.ymin = data.ymin
1176        new_plot.ymax = data.ymax
1177        new_plot.xmin = data.xmin
1178        new_plot.xmax = data.xmax
1179        title = data.title
1180        _yaxis, _yunit = data.get_yaxis()
1181        _xaxis, _xunit = data.get_xaxis()
1182        new_plot.xaxis(str(_xaxis), str(_xunit))
1183        new_plot.yaxis(str(_yaxis), str(_yunit))
1184
1185        new_plot.is_data = False
1186        if data.is_data:
1187            data_name = str(data.name)
1188        else:
1189            data_name = str(model.__class__.__name__) + '2d'
1190
1191        if len(title) > 1:
1192            new_plot.title = "Gen Theory for %s " % model.name + data_name
1193        new_plot.name = new_plot.id
1194        new_plot.label = new_plot.id
1195        #theory_data = deepcopy(new_plot)
1196        if self.parent.parent != None:
1197            self.parent.parent.update_theory(data_id=data.id,
1198                                           theory=new_plot,
1199                                           state=state)
1200        title = new_plot.title
1201        num_graph = str(self.graph_num)
1202        wx.CallAfter(self.parent.draw_graph, new_plot,
1203                     title="GEN Graph %s: " % num_graph + new_plot.id)
1204        self.graph_num += 1
1205
1206    def set_scale2d(self, scale):
1207        """
1208        Set SLD plot scale
1209        """
1210        self.scale2d = None
1211
1212    def on_panel_close(self, event):
1213        """
1214        On Close SLD panel
1215        """
1216        #Not implemented   
1217
1218class OmfPanel(ScrolledPanel, PanelBase):
1219    """
1220        Provides the sas gen calculator GUI.
1221    """
1222    ## Internal nickname for the window, used by the AUI manager
1223    window_name = "SLD Pixel Info"
1224    ## Name to appear on the window title bar
1225    window_caption = "SLD Pixel Info "
1226
1227    def __init__(self, parent, *args, **kwds):
1228        ScrolledPanel.__init__(self, parent, style=wx.RAISED_BORDER,
1229                               *args, **kwds)
1230        PanelBase.__init__(self)
1231        #Font size
1232        self.SetWindowVariant(variant=FONT_VARIANT)
1233        self.SetupScrolling()
1234        # Object that receive status event
1235        self.parent = parent
1236        self.sld_data = sas_gen.MagSLD([0], [0], [0])
1237        self.sld_ctl = None
1238        self.default_shape = 'rectangular'
1239        self._do_layout()
1240
1241    def set_slddata(self, slddata):
1242        """
1243        Set sld data related items
1244        """
1245        self.sld_data = slddata
1246        self._set_slddata_ctr_val(slddata)
1247        # Make sure that self._set_slddata_ctr_val() is finished
1248        wx.CallAfter(self._set_omfdata_ctr, slddata)
1249
1250    def get_sld_val(self):
1251        """
1252        Set sld_n of slddata on sld input
1253        """
1254        sld_sets = {}
1255        if not self.sld_data.is_data:
1256            self._get_other_val()
1257        for list in self.slds:
1258            if list[1].IsEnabled():
1259                list[1].SetBackgroundColour("white")
1260                list[1].Refresh()
1261                try:
1262                    val = float(list[1].GetValue())
1263                    sld_sets[list[0]] = val
1264                except:
1265                    flag = _set_error(self, list[1])
1266                    if not flag:
1267                        return self.sld_data
1268            else:
1269               sld_sets[list[0]] = None
1270        for key in sld_sets.keys():
1271            key_low = key.lower()
1272            if key_low.count('mx') > 0:
1273                if sld_sets[key] == None:
1274                    sld_sets[key] = self.sld_data.sld_mx
1275                mx = sld_sets[key]
1276            elif key_low.count('my') > 0:
1277                if sld_sets[key] == None:
1278                    sld_sets[key] = self.sld_data.sld_my
1279                my = sld_sets[key]
1280            elif key_low.count('mz') > 0:
1281                if sld_sets[key] == None:
1282                    sld_sets[key] = self.sld_data.sld_mz
1283                mz = sld_sets[key]
1284            else:
1285                if sld_sets[key] != None:
1286                    self.sld_data.set_sldn(sld_sets[key])
1287        self.sld_data.set_sldms(mx, my, mz)
1288        self._set_slddata_ctr_val(self.sld_data)
1289
1290        return self.sld_data
1291
1292    def get_pix_volumes(self):
1293        """
1294        Get the pixel volume
1295        """
1296        vol = self.sld_data.vol_pix
1297
1298        return vol
1299
1300    def _get_other_val(self):
1301        """
1302        """
1303        omfdata = sas_gen.OMFData()
1304        sets = {}
1305        try:
1306            for lst in self.stepsize:
1307                if lst[1].IsEnabled():
1308                    val = float(lst[1].GetValue())
1309                    sets[lst[0]] = val
1310                else:
1311                    sets[lst[0]] = None
1312                    return
1313            for lst in self.nodes:
1314                if lst[1].IsEnabled():
1315                    val = float(lst[1].GetValue())
1316                    sets[lst[0]] = val
1317                else:
1318                    sets[lst[0]] = None
1319                    return
1320
1321            for key in sets.keys():
1322                setattr(omfdata, key, sets[key])
1323
1324            omf2sld = sas_gen.OMF2SLD()
1325            omf2sld.set_data(omfdata, self.default_shape)
1326            self.sld_data = omf2sld.output
1327            self.sld_data.is_data = False
1328            self.sld_data.filename = "Default SLD Profile"
1329        except:
1330            msg = "OMF Panel: %s" % sys.exc_value
1331            infor = 'Error'
1332            #logging.error(msg)
1333            if self.parent.parent != None:
1334                # inform msg to wx
1335                wx.PostEvent(self.parent.parent,
1336                        StatusEvent(status=msg, info=infor))
1337                self.SetFocus()
1338
1339    def _set_slddata_ctr_val(self, slddata):
1340        """
1341        Set slddata crl
1342        """
1343        try:
1344            val = str(len(slddata.sld_n))
1345        except:
1346            val = 'Unknown'
1347        self.npix_ctl.SetValue(val)
1348
1349    def _set_omfdata_ctr(self, omfdata):
1350        """
1351        Set the textctr box values
1352        """
1353
1354        if omfdata == None:
1355            self._set_none_text()
1356            return
1357        nodes_list = self._get_nodes_key_list(omfdata)
1358        step_list = self._get_step_key_list(omfdata)
1359        for ctr_list in self.nodes:
1360            for key in nodes_list.keys():
1361                if ctr_list[0] == key:
1362                    ctr_list[1].SetValue(format_number(nodes_list[key], True))
1363                    ctr_list[1].Enable(not omfdata.is_data)
1364                    break
1365        for ctr_list in self.stepsize:
1366            for key in step_list.keys():
1367                if ctr_list[0] == key:
1368                    ctr_list[1].SetValue(format_number(step_list[key], True))
1369                    ctr_list[1].Enable(not omfdata.is_data)
1370                    break
1371
1372    def _set_none_text(self):
1373        """
1374        Set Unknown in textctrls
1375        """
1376        val = 'Unknown'
1377        for ctr_list in self.nodes:
1378            ctr_list[1].SetValue(val)
1379        for ctr_list in self.stepsize:
1380            ctr_list[1].SetValue(val)
1381
1382    def _define_structure(self):
1383        """
1384        Define the main sizers building to build this application.
1385        """
1386        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
1387
1388        self.npixels_sizer = wx.BoxSizer(wx.HORIZONTAL)
1389        self.box_sld = wx.StaticBox(self, -1,
1390                                    str("Mean SLD"))
1391        self.box_node = wx.StaticBox(self, -1, str("Nodes"))
1392        self.boxsizer_sld = wx.StaticBoxSizer(self.box_sld, wx.VERTICAL)
1393        self.box_stepsize = wx.StaticBox(self, -1, str("Step Size"))
1394        self.boxsizer_node = wx.StaticBoxSizer(self.box_node, wx.VERTICAL)
1395        self.boxsizer_stepsize = wx.StaticBoxSizer(self.box_stepsize,
1396                                                    wx.VERTICAL)
1397        self.sld_sizer = wx.BoxSizer(wx.HORIZONTAL)
1398        self.node_sizer = wx.BoxSizer(wx.HORIZONTAL)
1399        self.step_sizer = wx.BoxSizer(wx.HORIZONTAL)
1400        self.hint_sizer = wx.BoxSizer(wx.HORIZONTAL)
1401        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
1402
1403    def _layout_npix(self):
1404        """
1405        Build No of pixels sizer
1406        """
1407        num_pix_text = wx.StaticText(self, -1, "No. of Pixels: ")
1408        self.npix_ctl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH, 20),
1409                                style=wx.TE_PROCESS_ENTER)
1410        self._set_slddata_ctr_val(self.sld_data)
1411        self._set_omfdata_ctr(self.sld_data)
1412        self.npixels_sizer.AddMany([(num_pix_text, 0,
1413                                          wx.EXPAND | wx.LEFT | wx.TOP, 5),
1414                                     (self.npix_ctl, 0,
1415                                     wx.EXPAND | wx.TOP, 5)])
1416
1417    def _layout_slds(self):
1418        """
1419        Build nuclear sld sizer
1420        """
1421        self.slds = []
1422        omfdata = self.sld_data
1423        if omfdata == None:
1424            raise
1425        sld_key_list = self._get_slds_key_list(omfdata)
1426        # Dic is not sorted
1427        key_list = [key for key in sld_key_list.keys()]
1428        # Sort here
1429        key_list.sort()
1430        is_data = self.sld_data.is_data
1431        sizer = wx.GridBagSizer(2, 3)
1432        ix = 0
1433        iy = -1
1434        for key in key_list:
1435            value = sld_key_list[key]
1436            iy += 1
1437            ix = 0
1438            name = wx.StaticText(self, -1, key)
1439            sizer.Add(name, (iy, ix), (1, 1), \
1440                            wx.EXPAND | wx.ADJUST_MINSIZE, 0)
1441            ## add parameter value
1442            ix += 1
1443            ctl = InputTextCtrl(self, -1, size=(_BOX_WIDTH, 20),
1444                                style=wx.TE_PROCESS_ENTER)
1445            ctl.SetValue(format_number(value, True))
1446            ctl.Enable(not is_data)
1447            sizer.Add(ctl, (iy, ix), (1, 1), wx.EXPAND)
1448            ## add unit
1449            ix += 1
1450            s_unit = '[' + omfdata.sld_unit + ']'
1451            unit = wx.StaticText(self, -1, s_unit)
1452            sizer.Add(unit, (iy, ix), (1, 1), \
1453                            wx.EXPAND | wx.ADJUST_MINSIZE, 0)
1454            self.slds.append([key, ctl, unit])
1455        self.sld_sizer.Add(sizer, 0, wx.LEFT, 10)
1456
1457    def _layout_nodes(self):
1458        """
1459        Fill the sizer containing data's name
1460        """
1461        self.nodes = []
1462        omfdata = self.sld_data
1463        if omfdata == None:
1464            raise
1465        key_list = self._get_nodes_key_list(omfdata)
1466        is_data = self.sld_data.is_data
1467        sizer = wx.GridBagSizer(2, 3)
1468        ix = 0
1469        iy = -1
1470        for key, value in key_list.iteritems():
1471            iy += 1
1472            ix = 0
1473            name = wx.StaticText(self, -1, key)
1474            sizer.Add(name, (iy, ix), (1, 1), \
1475                            wx.EXPAND | wx.ADJUST_MINSIZE, 0)
1476            ## add parameter value
1477            ix += 1
1478            ctl = InputTextCtrl(self, -1, size=(_BOX_WIDTH, 20),
1479                                style=wx.TE_PROCESS_ENTER)
1480            ctl.Bind(wx.EVT_TEXT, self._onparamEnter)
1481            ctl.SetValue(format_number(value, True))
1482            ctl.Enable(not is_data)
1483            sizer.Add(ctl, (iy, ix), (1, 1), wx.EXPAND)
1484            ## add unit
1485            ix += 1
1486            unit = wx.StaticText(self, -1, '')
1487            sizer.Add(unit, (iy, ix), (1, 1), \
1488                            wx.EXPAND | wx.ADJUST_MINSIZE, 0)
1489            self.nodes.append([key, ctl, unit])
1490        self.node_sizer.Add(sizer, 0, wx.LEFT, 10)
1491
1492    def _layout_stepsize(self):
1493        """
1494        Fill the sizer containing slit size information
1495        """
1496        self.stepsize = []
1497        omfdata = self.sld_data
1498        if omfdata == None:
1499            raise
1500        key_list = self._get_step_key_list(omfdata)
1501        is_data = self.sld_data.is_data
1502        sizer = wx.GridBagSizer(2, 3)
1503        ix = 0
1504        iy = -1
1505        #key_list.sort()
1506        for key, value in key_list.iteritems():
1507            iy += 1
1508            ix = 0
1509            name = wx.StaticText(self, -1, key)
1510            sizer.Add(name, (iy, ix), (1, 1), \
1511                            wx.EXPAND | wx.ADJUST_MINSIZE, 0)
1512            ## add parameter value
1513            ix += 1
1514            ctl = InputTextCtrl(self, -1, size=(_BOX_WIDTH, 20),
1515                                style=wx.TE_PROCESS_ENTER)
1516            ctl.Bind(wx.EVT_TEXT, self._onstepsize)
1517            ctl.SetValue(format_number(value, True))
1518            ctl.Enable(not is_data)
1519            sizer.Add(ctl, (iy, ix), (1, 1), wx.EXPAND)
1520            ## add unit
1521            ix += 1
1522            p_unit = '[' + omfdata.pos_unit + ']'
1523            unit = wx.StaticText(self, -1, p_unit)
1524            sizer.Add(unit, (iy, ix), (1, 1), \
1525                            wx.EXPAND | wx.ADJUST_MINSIZE, 0)
1526            self.stepsize.append([key, ctl, unit])
1527        self.step_sizer.Add(sizer, 0, wx.LEFT, 10)
1528
1529    def _layout_hint(self):
1530        """
1531        Fill the sizer containing hint
1532        """
1533        hint_msg = "Load an omf or 3d sld profile data file."
1534        self.hint_txt = wx.StaticText(self, -1, hint_msg)
1535        self.hint_sizer.AddMany([(self.hint_txt, 0, wx.LEFT, 15)])
1536
1537    def _layout_button(self):
1538        """
1539        Do the layout for the button widgets
1540        """
1541        self.bt_draw = wx.Button(self, wx.NewId(), 'Draw Points')
1542        self.bt_draw.Bind(wx.EVT_BUTTON, self.on_sld_draw)
1543        self.bt_draw.SetToolTipString("Draw a scatter plot for sld profile.")
1544        self.bt_save = wx.Button(self, wx.NewId(), 'Save SLD Data')
1545        self.bt_save.Bind(wx.EVT_BUTTON, self.on_save)
1546        self.bt_save.Enable(False)
1547        self.bt_save.SetToolTipString("Save SLD data.")
1548        self.button_sizer.AddMany([(self.bt_draw, 0, wx.LEFT, 10),
1549                                   (self.bt_save, 0, wx.LEFT, 10)])
1550
1551    def _do_layout(self):
1552        """
1553        Draw omf panel content, used to define sld s.
1554
1555        """
1556        self._define_structure()
1557        self._layout_nodes()
1558        self._layout_stepsize()
1559        self._layout_npix()
1560        self._layout_slds()
1561        #self._layout_hint()
1562        self._layout_button()
1563        self.boxsizer_node.AddMany([(self.node_sizer, 0,
1564                                    wx.EXPAND | wx.TOP, 5),
1565                                     (self.hint_sizer, 0,
1566                                     wx.EXPAND | wx.TOP | wx.BOTTOM, 5)])
1567        self.boxsizer_stepsize.AddMany([(self.step_sizer, 0,
1568                                     wx.EXPAND | wx.TOP | wx.BOTTOM, 5), ])
1569        self.boxsizer_sld.AddMany([(self.sld_sizer, 0,
1570                                     wx.EXPAND | wx.BOTTOM, 5), ])
1571        self.main_sizer.AddMany([(self.npixels_sizer, 0, wx.EXPAND | wx.ALL, 10),
1572                        (self.boxsizer_sld, 0, wx.EXPAND | wx.ALL, 10),
1573                        (self.boxsizer_node, 0, wx.EXPAND | wx.ALL, 10),
1574                        (self.boxsizer_stepsize, 0, wx.EXPAND | wx.ALL, 10),
1575                        (self.button_sizer, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)])
1576        self.SetSizer(self.main_sizer)
1577        self.SetAutoLayout(True)
1578
1579    def _get_nodes_key_list(self, data):
1580        """
1581        Return nodes key list
1582
1583        :Param data: OMFData
1584        """
1585        key_list = {'xnodes' : data.xnodes,
1586                    'ynodes' : data.ynodes,
1587                    'znodes' : data.znodes}
1588        return key_list
1589
1590    def _get_slds_key_list(self, data):
1591        """
1592        Return nodes key list
1593
1594        :Param data: OMFData
1595        """
1596        key_list = {'Nucl.' : data.sld_n,
1597                    'Mx' : data.sld_mx,
1598                    'My' : data.sld_my,
1599                    'Mz' : data.sld_mz}
1600        return key_list
1601
1602    def _get_step_key_list(self, data):
1603        """
1604        Return step key list
1605
1606        :Param data: OMFData
1607        """
1608        key_list = {'xstepsize' : data.xstepsize,
1609                    'ystepsize' : data.ystepsize,
1610                    'zstepsize' : data.zstepsize}
1611        return key_list
1612
1613    def set_sld_ctr(self, sld_data):
1614        """
1615        Set sld textctrls
1616        """
1617        if sld_data == None:
1618            for ctr_list in self.slds:
1619                ctr_list[1].Enable(False)
1620                #break   
1621            return
1622
1623        self.sld_data = sld_data
1624        sld_list = self._get_slds_key_list(sld_data)
1625        for ctr_list in self.slds:
1626            for key in sld_list.keys():
1627                if ctr_list[0] == key:
1628                    min_val = numpy.min(sld_list[key])
1629                    max_val = numpy.max(sld_list[key])
1630                    mean_val = numpy.mean(sld_list[key])
1631                    enable = (min_val == max_val) and \
1632                             sld_data.pix_type == 'pixel'
1633                    ctr_list[1].SetValue(format_number(mean_val, True))
1634                    ctr_list[1].Enable(enable)
1635                    #ctr_list[2].SetLabel("[" + sld_data.sld_unit + "]")
1636                    break
1637
1638    def on_sld_draw(self, event):
1639        """
1640        Draw sld profile as scattered plot
1641        """
1642        self.parent.sld_draw()
1643
1644    def on_save(self, event):
1645        """
1646        Close the window containing this panel
1647        """
1648        flag = True
1649        flag = self.check_inputs()
1650        if not flag:
1651            return
1652        self.sld_data = self.get_sld_val()
1653        self.parent.set_main_panel_sld_data(self.sld_data)
1654
1655        reader = sas_gen.SLDReader()
1656        extension = '*.sld'
1657        path = None
1658        data = None
1659        location = self.parent.get_path()
1660        dlg = wx.FileDialog(self, "Save sld file",
1661                            location, "sld_file",
1662                             extension,
1663                             wx.SAVE)
1664        if dlg.ShowModal() == wx.ID_OK:
1665            path = dlg.GetPath()
1666            self.parent.set_file_location(os.path.dirname(path))
1667        else:
1668            return None
1669        dlg.Destroy()
1670        try:
1671            if path is None:
1672                return
1673
1674            data = self.parent.get_sld_data()
1675            fName = os.path.splitext(path)[0] + '.' + extension.split('.')[-1]
1676            if data != None:
1677                try:
1678                    reader.write(fName, data)
1679                except:
1680                    raise
1681            else:
1682                msg = "%s cannot write %s\n" % ('Generic Scattering', str(path))
1683                infor = 'Error'
1684                #logging.error(msg)
1685                if self.parent.parent != None:
1686                    # inform msg to wx
1687                    wx.PostEvent(self.parent.parent,
1688                            StatusEvent(status=msg, info=infor))
1689                    self.SetFocus()
1690            return
1691        except:
1692            msg = "Error occurred while saving. "
1693            infor = 'Error'
1694            if self.parent.parent != None:
1695                # inform msg to wx
1696                wx.PostEvent(self.parent.parent,
1697                        StatusEvent(status=msg, info=infor))
1698                self.SetFocus()
1699
1700    def _onparamEnter(self, event):
1701        """
1702        """
1703        flag = True
1704        if event != None:
1705            event.Skip()
1706            ctl = event.GetEventObject()
1707            ctl.SetBackgroundColour("white")
1708            #_set_error(self, ctl)
1709        try:
1710            float(ctl.GetValue())
1711        except:
1712            flag = _set_error(self, ctl)
1713        if flag:
1714            npts = 1
1715            for item in self.nodes:
1716                n_val = float(item[1].GetValue())
1717                if n_val <= 0:
1718                    item[1].SetBackgroundColour("pink")
1719                    npts = -1
1720                    break
1721                if numpy.isfinite(n_val):
1722                    npts *= int(n_val)
1723            if npts > 0:
1724                nop = self.set_npts_from_slddata()
1725                if nop == None:
1726                    nop = npts
1727                self.display_npts(nop)
1728
1729        ctl.Refresh()
1730        return flag
1731
1732    def _set_volume_ctr_val(self, npts):
1733        """
1734        Set total volume
1735        """
1736        total_volume = npts * self.sld_data.vol_pix[0]
1737        self.parent.set_volume_ctr_val(total_volume)
1738
1739    def _onstepsize(self, event):
1740        """
1741        On stepsize event
1742        """
1743        flag = True
1744        if event != None:
1745            event.Skip()
1746            ctl = event.GetEventObject()
1747            ctl.SetBackgroundColour("white")
1748
1749        if flag and not self.sld_data.is_data:#ctl.IsEnabled():
1750            s_size = 1.0
1751            try:
1752                for item in self.stepsize:
1753                    s_val = float(item[1].GetValue())
1754                    if s_val <= 0:
1755                        item[1].SetBackgroundColour("pink")
1756                        ctl.Refresh()
1757                        return
1758                    if numpy.isfinite(s_val):
1759                        s_size *= s_val
1760                self.sld_data.set_pixel_volumes(s_size)
1761                if ctl.IsEnabled():
1762                    total_volume = sum(self.sld_data.vol_pix)
1763                    self.parent.set_volume_ctr_val(total_volume)
1764            except:
1765                pass
1766        ctl.Refresh()
1767
1768
1769    def set_npts_from_slddata(self):
1770        """
1771        Set total n. of points form the sld data
1772        """
1773        try:
1774            sld_data = self.parent.get_sld_from_omf()
1775            #nop = (nop * numpy.pi) / 6
1776            nop = len(sld_data.sld_n)
1777        except:
1778            nop = None
1779        return nop
1780
1781    def display_npts(self, nop):
1782        """
1783        Displays Npts ctrl
1784        """
1785        try:
1786            self.npix_ctl.SetValue(str(nop))
1787            self.npix_ctl.Refresh()
1788            self.parent.set_etime()
1789            wx.CallAfter(self._set_volume_ctr_val, nop)
1790        except:
1791            # On Init
1792            pass
1793
1794    def check_inputs(self):
1795        """
1796        check if the inputs are valid
1797        """
1798        flag = self._check_input_helper(self.slds)
1799        if flag:
1800            flag = self._check_input_helper(self.nodes)
1801        if flag:
1802            flag = self._check_input_helper(self.stepsize)
1803        return flag
1804
1805    def _check_input_helper(self, list):
1806        """
1807        Check list values
1808        """
1809        flag = True
1810        for item in list:
1811            item[1].SetBackgroundColour("white")
1812            item[1].Refresh()
1813            try:
1814                float(item[1].GetValue())
1815            except:
1816                flag = _set_error(self, item[1])
1817                break
1818        return flag
1819
1820class SasGenWindow(widget.CHILD_FRAME):
1821    """
1822    GEN SAS main window
1823    """
1824    def __init__(self, parent=None, manager=None, title="Generic Scattering Calculator",
1825                size=(PANEL_WIDTH * 1.4, PANEL_HEIGHT * 1.65), *args, **kwds):
1826        """
1827        Init
1828        """
1829        kwds['size'] = size
1830        kwds['title'] = title
1831        widget.CHILD_FRAME.__init__(self, parent, *args, **kwds)
1832        self.parent = parent
1833        self.base = manager
1834        self.omfpanel = OmfPanel(parent=self)
1835        self.panel = SasGenPanel(parent=self)
1836        self.data = None
1837        self.omfdata = sas_gen.OMFData()
1838        self.sld_data = None
1839        self._default_save_location = os.getcwd()
1840
1841        self._mgr = aui.AuiManager(self)
1842        self._mgr.SetDockSizeConstraint(0.5, 0.5)
1843        self._plot_title = ''
1844        self.scale2d = 'log_{10}'
1845        self.Bind(wx.EVT_CLOSE, self.on_close)
1846
1847
1848        self.build_panels()
1849        self.SetPosition((wx.LEFT, PANEL_TOP))
1850        self.Show(True)
1851
1852    def build_panels(self):
1853        """
1854        """
1855
1856        self.set_sld_data(self.sld_data)
1857        self._mgr.AddPane(self.panel, aui.AuiPaneInfo().
1858                              Name(self.panel.window_name).
1859                              CenterPane().
1860                              # This is where we set the size of
1861                              # the application window
1862                              BestSize(wx.Size(PANEL_WIDTH,
1863                                               PANEL_HEIGHT)).
1864                              Show())
1865        self._mgr.AddPane(self.omfpanel, aui.AuiPaneInfo().
1866                              Name(self.omfpanel.window_name).
1867                              Caption(self.omfpanel.window_caption).
1868                              CloseButton(False).
1869                              Right().
1870                              Floatable(False).
1871                              BestSize(wx.Size(PANEL_WIDTH / 2.5, PANEL_HEIGHT)).
1872                              Show())
1873        self._mgr.Update()
1874
1875    def get_sld_data(self):
1876        """
1877        Return slddata
1878        """
1879        return self.sld_data
1880
1881    def get_sld_from_omf(self):
1882        """
1883        """
1884        self.sld_data = self.omfpanel.get_sld_val()
1885        return self.sld_data
1886
1887    def set_sld_n(self, sld):
1888        """
1889        """
1890        self.panel.sld_data = sld
1891        self.panel.model.set_sld_data(sld)
1892
1893    def set_sld_data(self, data):
1894        """
1895        Set omfdata
1896        """
1897        if data == None:
1898            return
1899        self.sld_data = data
1900        enable = (not data == None)
1901        self._set_omfpanel_sld_data(self.sld_data)
1902        self.omfpanel.bt_save.Enable(enable)
1903        self.set_etime()
1904
1905    def set_omfpanel_npts(self):
1906        """
1907        Set Npts in omf panel
1908        """
1909        nop = self.omfpanel.set_npts_from_slddata()
1910        self.omfpanel.display_npts(nop)
1911
1912    def _set_omfpanel_sld_data(self, data):
1913        """
1914        Set sld_data in omf panel
1915        """
1916        self.omfpanel.set_slddata(data)
1917        self.omfpanel.set_sld_ctr(data)
1918
1919    def check_omfpanel_inputs(self):
1920        """
1921        Check OMF panel inputs
1922        """
1923        return self.omfpanel.check_inputs()
1924
1925    def set_main_panel_sld_data(self, sld_data):
1926        """
1927        """
1928        self.sld_data = sld_data
1929
1930    def set_file_location(self, path):
1931        """
1932        File location
1933        """
1934        self._default_save_location = path
1935
1936    def get_path(self):
1937        """
1938        File location
1939        """
1940        return self._default_save_location
1941
1942    def draw_graph(self, plot, title=''):
1943        """
1944        """
1945        try:
1946            wx.PostEvent(self.parent, NewPlotEvent(plot=plot, title=title))
1947        except:
1948            # standalone
1949            frame = PlotFrame(self, -1, 'testView', self.scale2d)
1950            #add_icon(self.parent, frame)
1951            frame.add_plot(plot)
1952            frame.SetTitle(title)
1953            frame.Show(True)
1954            frame.SetFocus()
1955
1956    def set_schedule_full_draw(self, panel=None, func='del'):
1957        """
1958        Send full draw to gui frame
1959        """
1960        if self.parent != None:
1961            self.parent.set_schedule_full_draw(panel, func)
1962
1963    def get_npix(self):
1964        """
1965        Get no. of pixels from omf panel
1966        """
1967        n_pix = self.omfpanel.npix_ctl.GetValue()
1968        return n_pix
1969
1970    def get_pix_volumes(self):
1971        """
1972        Get a pixel volume
1973        """
1974        vol = self.omfpanel.get_pix_volumes()
1975        return vol
1976
1977    def set_volume_ctr_val(self, val):
1978        """
1979        Set volume txtctl value
1980        """
1981        try:
1982            self.panel.set_volume_ctl_val(str(val))
1983        except:
1984            print "self.panel is not initialized yet"
1985
1986    def set_omfpanel_default_shap(self, shape):
1987        """
1988        Set default_shape in omfpanel
1989        """
1990        self.omfpanel.default_shape = shape
1991
1992    def set_etime(self):
1993        """
1994        Sets est. computation time on panel
1995        """
1996        self.panel.set_est_time()
1997
1998    def get_sld_data_from_omf(self):
1999        """
2000        """
2001        data = self.omfpanel.get_sld_val()
2002        return data
2003
2004    def set_scale2d(self, scale):
2005        """
2006        """
2007        self.scale2d = scale
2008
2009    def on_panel_close(self, event):
2010        """
2011        """
2012        #Not implemented
2013
2014    def on_open_file(self, event):
2015        """
2016        On Open
2017        """
2018        self.panel.on_load_data(event)
2019
2020    def sld_draw(self):
2021        """
2022        sld draw
2023        """
2024        self.panel.sld_draw(event=None, has_arrow=False)
2025
2026    def on_save_file(self, event):
2027        """
2028        On Close
2029        """
2030        self.omfpanel.on_save(event)
2031
2032    def on_close(self, event):
2033        """
2034        Close
2035        """
2036        if self.base != None:
2037            self.base.gen_frame = None
2038        self.Destroy()
2039
2040if __name__ == "__main__":
2041    app = wx.PySimpleApp()
2042    widget.CHILD_FRAME = wx.Frame
2043    SGframe = SasGenWindow()
2044    SGframe.Show(True)
2045    app.MainLoop()
Note: See TracBrowser for help on using the repository browser.