source: sasview/src/sas/sasgui/perspectives/calculator/gen_scatter_panel.py @ bf3ca1e

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

linked new help to all Tools menu panels remaining.

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