Ignore:
Timestamp:
Oct 24, 2017 2:44:26 AM (7 years ago)
Author:
Piotr Rozyczko <rozyczko@…>
Branches:
ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
Children:
fca1f50, d6b234b
Parents:
16afe01 (diff), 5582b078 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into ESS_GUI

Location:
src/sas/sasgui/guiframe/local_perspectives
Files:
1 added
1 deleted
9 edited
1 moved

Legend:

Unmodified
Added
Removed
  • src/sas/sasgui/guiframe/local_perspectives/data_loader/data_loader.py

    r235f514 rb963b20  
    1010logger = logging.getLogger(__name__) 
    1111 
     12from sas import get_local_config 
     13 
    1214from sas.sascalc.dataloader.loader import Loader 
     15from sas.sascalc.dataloader.loader_exceptions import NoKnownLoaderException 
     16 
    1317from sas.sasgui.guiframe.plugin_base import PluginBase 
    1418from sas.sasgui.guiframe.events import StatusEvent 
    1519from sas.sasgui.guiframe.gui_style import GUIFRAME 
    1620from sas.sasgui.guiframe.gui_manager import DEFAULT_OPEN_FOLDER 
    17 try: 
    18     # Try to find a local config 
    19     import imp 
    20     path = os.getcwd() 
    21     if(os.path.isfile("%s/%s.py" % (path, 'local_config'))) or \ 
    22         (os.path.isfile("%s/%s.pyc" % (path, 'local_config'))): 
    23         fObj, path, descr = imp.find_module('local_config', [path]) 
    24         config = imp.load_module('local_config', fObj, path, descr) 
    25     else: 
    26         # Try simply importing local_config 
    27         import local_config as config 
    28 except: 
    29     # Didn't find local config, load the default 
    30     import sas.sasgui.guiframe.config as config 
    31  
    32 if config is None: 
    33     import sas.sasgui.guiframe.config as config 
    34  
    35  
     21 
     22config = get_local_config() 
    3623extension_list = [] 
    3724if config.APPLICATION_STATE_EXTENSION is not None: 
     
    4128APPLICATION_WLIST = config.APPLICATION_WLIST 
    4229 
     30 
    4331class Plugin(PluginBase): 
    4432 
     
    5644        """ 
    5745        # menu for data files 
    58         menu_list = [] 
    5946        data_file_hint = "load one or more data in the application" 
    6047        menu_list = [('&Load Data File(s)', data_file_hint, self.load_data)] 
    6148        gui_style = self.parent.get_style() 
    6249        style = gui_style & GUIFRAME.MULTIPLE_APPLICATIONS 
    63         style1 = gui_style & GUIFRAME.DATALOADER_ON 
    6450        if style == GUIFRAME.MULTIPLE_APPLICATIONS: 
    6551            # menu for data from folder 
     
    10288        self.get_data(file_list) 
    10389 
    104  
    10590    def can_load_data(self): 
    10691        """ 
     
    10893        """ 
    10994        return True 
    110  
    11195 
    11296    def _load_folder(self, event): 
     
    140124        """ 
    141125        if error is not None or str(error).strip() != "": 
    142             dial = wx.MessageDialog(self.parent, str(error), 'Error Loading File', 
     126            dial = wx.MessageDialog(self.parent, str(error), 
     127                                    'Error Loading File', 
    143128                                    wx.OK | wx.ICON_EXCLAMATION) 
    144129            dial.ShowModal() 
     
    149134        """ 
    150135        if os.path.isdir(path): 
    151             return [os.path.join(os.path.abspath(path), filename) for filename in os.listdir(path)] 
     136            return [os.path.join(os.path.abspath(path), filename) for filename 
     137                    in os.listdir(path)] 
    152138 
    153139    def _process_data_and_errors(self, item, p_file, output, message): 
     
    178164        for p_file in path: 
    179165            basename = os.path.basename(p_file) 
     166            # Skip files that start with a period 
     167            if basename.startswith("."): 
     168                msg = "The folder included a potential hidden file - %s." \ 
     169                      % basename 
     170                msg += " Do you wish to load this file as data?" 
     171                msg_box = wx.MessageDialog(None, msg, 'Warning', 
     172                                           wx.OK | wx.CANCEL) 
     173                if msg_box.ShowModal() == wx.ID_CANCEL: 
     174                    continue 
    180175            _, extension = os.path.splitext(basename) 
    181176            if extension.lower() in EXTENSIONS: 
     
    213208                info="info") 
    214209 
    215             except: 
    216                 logger.error(sys.exc_value) 
    217  
    218                 error_message = "The Data file you selected could not be loaded.\n" 
    219                 error_message += "Make sure the content of your file" 
    220                 error_message += " is properly formatted.\n" 
    221                 error_message += "When contacting the SasView team, mention the" 
    222                 error_message += " following:\n" 
    223                 error_message += "Error: " + str(sys.exc_info()[1]) 
    224                 file_errors[basename] = [error_message] 
    225                 self.load_update(output=output, message=error_message, info="warning") 
     210            except NoKnownLoaderException as e: 
     211                exception_occurred = True 
     212                logger.error(e.message) 
     213 
     214                error_message = "Loading data failed!\n" + e.message 
     215                self.load_update(output=None, message=e.message, info="warning") 
     216 
     217            except Exception as e: 
     218                exception_occurred = True 
     219                logger.error(e.message) 
     220 
     221                file_err = "The Data file you selected could not be " 
     222                file_err += "loaded.\nMake sure the content of your file" 
     223                file_err += " is properly formatted.\n" 
     224                file_err += "When contacting the SasView team, mention the" 
     225                file_err += " following:\n" 
     226                file_err += e.message 
     227                file_errors[basename] = [file_err] 
    226228 
    227229        if len(file_errors) > 0: 
     
    233235                    error_message += message + "\n" 
    234236                error_message += "\n" 
    235             self.load_update(output=output, message=error_message, info="error") 
    236  
    237         self.load_complete(output=output, message="Loading data complete!", 
    238             info="info") 
     237            if not exception_occurred: # Some data loaded but with errors 
     238                self.load_update(output=output, message=error_message, info="error") 
     239 
     240        if not exception_occurred: # Everything loaded as expected 
     241            self.load_complete(output=output, message="Loading data complete!", 
     242                               info="info") 
     243        else: 
     244            self.load_complete(output=None, message=error_message, info="error") 
     245 
    239246 
    240247    def load_update(self, output=None, message="", info="warning"): 
     
    245252            wx.PostEvent(self.parent, StatusEvent(status=message, info=info, 
    246253                                                  type="progress")) 
    247     def load_complete(self, output, message="", error_message="", path=None, 
    248                       info="warning"): 
    249         """ 
    250          post message to  status bar and return list of data 
    251         """ 
    252         wx.PostEvent(self.parent, StatusEvent(status=message, 
    253                                               info=info, 
     254 
     255    def load_complete(self, output, message="", info="warning"): 
     256        """ 
     257         post message to status bar and return list of data 
     258        """ 
     259        wx.PostEvent(self.parent, StatusEvent(status=message, info=info, 
    254260                                              type="stop")) 
    255         # if error_message != "": 
    256         #    self.load_error(error_message) 
    257         self.parent.add_data(data_list=output) 
     261        if output is not None: 
     262            self.parent.add_data(data_list=output) 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter2D.py

    r7432acb r3e5648b  
    361361                if self.slicer.__class__.__name__ != "BoxSum": 
    362362                    wx_id = ids.next() 
    363                     slicerpop.Append(wx_id, '&Edit Slicer Parameters') 
     363                    name = '&Edit Slicer Parameters and Batch Slicing' 
     364                    slicerpop.Append(wx_id, name) 
    364365                    wx.EVT_MENU(self, wx_id, self._onEditSlicer) 
    365366            slicerpop.AppendSeparator() 
     
    532533 
    533534        """ 
    534         ## Clear current slicer 
     535        # Clear current slicer 
    535536        if self.slicer is not None: 
    536537            self.slicer.clear() 
    537         ## Create a new slicer 
     538        # Create a new slicer 
    538539        self.slicer_z += 1 
    539540        self.slicer = slicer(self, self.subplot, zorder=self.slicer_z) 
    540541        self.subplot.set_ylim(self.data2D.ymin, self.data2D.ymax) 
    541542        self.subplot.set_xlim(self.data2D.xmin, self.data2D.xmax) 
    542         ## Draw slicer 
     543        # Draw slicer 
    543544        self.update() 
    544545        self.slicer.update() 
     
    572573        npt = math.floor(npt) 
    573574        from sas.sascalc.dataloader.manipulations import CircularAverage 
    574         ## compute the maximum radius of data2D 
     575        # compute the maximum radius of data2D 
    575576        self.qmax = max(math.fabs(self.data2D.xmax), 
    576577                        math.fabs(self.data2D.xmin)) 
     
    578579                        math.fabs(self.data2D.ymin)) 
    579580        self.radius = math.sqrt(math.pow(self.qmax, 2) + math.pow(self.ymax, 2)) 
    580         ##Compute beam width 
     581        # Compute beam width 
    581582        bin_width = (self.qmax + self.qmax) / npt 
    582         ## Create data1D circular average of data2D 
     583        # Create data1D circular average of data2D 
    583584        Circle = CircularAverage(r_min=0, r_max=self.radius, 
    584585                                 bin_width=bin_width) 
     
    599600        new_plot.name = "Circ avg " + self.data2D.name 
    600601        new_plot.source = self.data2D.source 
    601         #new_plot.info = self.data2D.info 
     602        # new_plot.info = self.data2D.info 
    602603        new_plot.interactive = True 
    603604        new_plot.detector = self.data2D.detector 
    604605 
    605         ## If the data file does not tell us what the axes are, just assume... 
     606        # If the data file does not tell us what the axes are, just assume... 
    606607        new_plot.xaxis("\\rm{Q}", "A^{-1}") 
    607608        if hasattr(self.data2D, "scale") and \ 
     
    615616        new_plot.id = "Circ avg " + self.data2D.name 
    616617        new_plot.is_data = True 
    617         self.parent.update_theory(data_id=self.data2D.id, \ 
    618                                        theory=new_plot) 
     618        self.parent.update_theory(data_id=self.data2D.id, theory=new_plot) 
    619619        wx.PostEvent(self.parent, 
    620620                     NewPlotEvent(plot=new_plot, title=new_plot.name)) 
     
    630630        """ 
    631631        if self.slicer is not None: 
    632             from SlicerParameters import SlicerParameterPanel 
     632            from parameters_panel_slicer import SlicerParameterPanel 
    633633            dialog = SlicerParameterPanel(self, -1, "Slicer Parameters") 
    634634            dialog.set_slicer(self.slicer.__class__.__name__, 
     
    668668        params = self.slicer.get_params() 
    669669        ## Create a new panel to display results of summation of Data2D 
    670         from slicerpanel import SlicerPanel 
     670        from parameters_panel_boxsum import SlicerPanel 
    671671        win = MDIFrame(self.parent, None, 'None', (100, 200)) 
    672672        new_panel = SlicerPanel(parent=win, id=-1, 
     
    758758        if default_name.count('.') > 0: 
    759759            default_name = default_name.split('.')[0] 
    760         #default_name += "_out" 
    761760        if self.parent is not None: 
    762761            self.parent.show_data2d(data, default_name) 
    763762 
    764763    def modifyGraphAppearance(self, e): 
    765         self.graphApp = graphAppearance(self, 'Modify graph appearance', legend=False) 
     764        self.graphApp = graphAppearance(self, 'Modify graph appearance', 
     765                                        legend=False) 
    766766        self.graphApp.setDefaults(self.grid_on, self.legend_on, 
    767767                                  self.xaxis_label, self.yaxis_label, 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/parameters_panel_boxsum.py

    r7432acb r37d461c  
    11import wx 
    22import wx.lib.newevent 
    3 #from copy import deepcopy 
     3from parameters_panel_slicer import SlicerParameterPanel 
    44from sas.sasgui.guiframe.utils import format_number 
    5 from sas.sasgui.guiframe.events import SlicerParameterEvent 
    6 from sas.sasgui.guiframe.events import EVT_SLICER_PARS 
    7 from sas.sasgui.guiframe.events import EVT_SLICER 
     5from sas.sasgui.guiframe.panel_base import PanelBase 
     6from sas.sasgui.guiframe.events import (SlicerParameterEvent, EVT_SLICER_PARS, 
     7                                        EVT_SLICER) 
    88 
    9 from sas.sasgui.guiframe.panel_base import PanelBase 
    109 
    1110class SlicerPanel(wx.Panel, PanelBase): 
     
    1312    Panel class to show the slicer parameters 
    1413    """ 
    15     #TODO: show units 
    16     #TODO: order parameters properly 
    17     ## Internal name for the AUI manager 
     14    # Internal name for the AUI manager 
    1815    window_name = "Slicer panel" 
    19     ## Title to appear on top of the window 
     16    # Title to appear on top of the window 
    2017    window_caption = "Slicer Panel" 
    2118    CENTER_PANE = False 
     
    2522        wx.Panel.__init__(self, parent, id, *args, **kwargs) 
    2623        PanelBase.__init__(self) 
    27         ## Initialization of the class 
     24        # Initialization of the class 
    2825        self.base = base 
    2926        if params is None: 
     
    4441        else: 
    4542            self.set_slicer(type, params) 
    46         ## Bindings 
    47         self.parent.Bind(EVT_SLICER, self.onEVT_SLICER) 
    48         self.parent.Bind(EVT_SLICER_PARS, self.onParamChange) 
    49  
    50     def onEVT_SLICER(self, event): 
    51         """ 
    52         Process EVT_SLICER events 
    53         When the slicer changes, update the panel 
    54  
    55         :param event: EVT_SLICER event 
    56  
    57         """ 
    58         event.Skip() 
    59         if event.obj_class is None: 
    60             self.set_slicer(None, None) 
    61         else: 
    62             self.set_slicer(event.type, event.params) 
     43        # Bindings 
     44        self.parent.Bind(EVT_SLICER, SlicerParameterPanel.on_evt_slicer) 
     45        self.parent.Bind(EVT_SLICER_PARS, SlicerParameterPanel.on_param_change) 
    6346 
    6447    def set_slicer(self, type, params): 
     
    8467            keys.sort() 
    8568            for item in keys: 
    86                 if not item.lower() in ["num_points", "avg", "avg_error", "sum", "sum_error"]: 
     69                if not item.lower() in ["num_points", "avg", "avg_error", "sum", 
     70                                        "sum_error"]: 
    8771                    n += 1 
    8872                    text = wx.StaticText(self, -1, item, style=wx.ALIGN_LEFT) 
    8973                    self.bck.Add(text, (n - 1, 0), 
    90                                  flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border=15) 
     74                                 flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 
     75                                 border=15) 
    9176                    ctl = wx.TextCtrl(self, -1, size=(80, 20), 
    9277                                      style=wx.TE_PROCESS_ENTER) 
     
    9580                    ctl.SetToolTipString(hint_msg) 
    9681                    ctl.SetValue(str(format_number(params[item]))) 
    97                     self.Bind(wx.EVT_TEXT_ENTER, self.onTextEnter) 
    98                     ctl.Bind(wx.EVT_SET_FOCUS, self.onSetFocus) 
    99                     ctl.Bind(wx.EVT_KILL_FOCUS, self.onTextEnter) 
     82                    self.Bind(wx.EVT_TEXT_ENTER, self.on_text_enter) 
     83                    ctl.Bind(wx.EVT_SET_FOCUS, self.on_set_focus) 
     84                    ctl.Bind(wx.EVT_KILL_FOCUS, self.on_text_enter) 
    10085                    self.parameters.append([item, ctl]) 
    101                     self.bck.Add(ctl, (n - 1, 1), flag=wx.TOP | wx.BOTTOM, border=0) 
     86                    self.bck.Add(ctl, (n - 1, 1), flag=wx.TOP | wx.BOTTOM, 
     87                                 border=0) 
    10288            for item in keys: 
    103                 if  item.lower() in ["num_points", "avg", "avg_error", "sum", "sum_error"]: 
     89                if item.lower() in ["num_points", "avg", "avg_error", "sum", 
     90                                    "sum_error"]: 
    10491                    n += 1 
    105                     text = wx.StaticText(self, -1, item + ": ", style=wx.ALIGN_LEFT) 
    106                     self.bck.Add(text, (n - 1, 0), flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 
     92                    text = wx.StaticText(self, -1, item + ": ", 
     93                                         style=wx.ALIGN_LEFT) 
     94                    self.bck.Add(text, (n - 1, 0), 
     95                                 flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 
    10796                                 border=15) 
    10897                    ctl = wx.StaticText(self, -1, 
     
    11099                                        style=wx.ALIGN_LEFT) 
    111100                    ctl.SetToolTipString("Result %s" % item) 
    112                     self.bck.Add(ctl, (n - 1, 1), flag=wx.TOP | wx.BOTTOM, border=0) 
     101                    self.bck.Add(ctl, (n - 1, 1), flag=wx.TOP | wx.BOTTOM, 
     102                                 border=0) 
    113103        self.bck.Layout() 
    114104        self.Layout() 
    115         psizer = self.parent.GetSizer() 
    116         if psizer is not None: 
    117             psizer.Layout() 
     105        p_sizer = self.parent.GetSizer() 
     106        if p_sizer is not None: 
     107            p_sizer.Layout() 
    118108 
    119     def onSetFocus(self, evt): 
     109    def on_set_focus(self, evt): 
    120110        """ 
    121111        Highlight the txtcrtl 
     
    126116        # Select the whole control, after this event resolves 
    127117        wx.CallAfter(widget.SetSelection, -1, -1) 
    128         return 
    129118 
    130     def onParamChange(self, evt): 
    131         """ 
    132         Receive and event and reset the text field contained in self.parameters 
    133  
    134         """ 
    135         evt.Skip() 
    136         for item in self.parameters: 
    137             if item[0] in evt.params: 
    138                 item[1].SetValue(format_number(evt.params[item[0]])) 
    139                 item[1].Refresh() 
    140  
    141     def onTextEnter(self, evt): 
     119    def on_text_enter(self, evt): 
    142120        """ 
    143121        Parameters have changed 
     
    149127            try: 
    150128                params[item[0]] = float(item[1].GetValue()) 
    151                 item[1].SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)) 
     129                item[1].SetBackgroundColour(wx.SystemSettings_GetColour( 
     130                    wx.SYS_COLOUR_WINDOW)) 
    152131                item[1].Refresh() 
    153132            except: 
     
    155134                item[1].SetBackgroundColour("pink") 
    156135                item[1].Refresh() 
    157  
    158         if has_error == False: 
     136        if not has_error: 
    159137            # Post parameter event 
    160             ## base is guiframe is this case 
     138            # base is guiframe is this case 
    161139            event = SlicerParameterEvent(type=self.type, params=params) 
    162140            wx.PostEvent(self.base, event) 
     
    166144        On Close Event 
    167145        """ 
    168         ID = self.uid 
    169         self.parent.delete_panel(ID) 
     146        uid = self.uid 
     147        self.parent.delete_panel(uid) 
    170148        self.frame.Destroy() 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/plotting.py

    r235f514 r2d9526d  
    1414import wx 
    1515import sys 
     16from copy import deepcopy 
    1617from sas.sasgui.guiframe.events import EVT_NEW_PLOT 
    1718from sas.sasgui.guiframe.events import EVT_PLOT_QRANGE 
     
    275276                action_check = True 
    276277            else: 
     278                if action_string == 'update': 
     279                    # Update all existing plots of data with this ID 
     280                    for data in event.plots: 
     281                        for panel in self.plot_panels.values(): 
     282                            if data.id in panel.plots.keys(): 
     283                                plot_exists = True 
     284                                # Pass each panel it's own copy of the data 
     285                                # that's being updated, otherwise things like 
     286                                # colour and line thickness are unintentionally 
     287                                # synced across panels 
     288                                self.update_panel(deepcopy(data), panel) 
     289                    return 
     290                     
    277291                group_id = event.group_id 
    278                 if group_id in self.plot_panels.keys(): 
     292                if group_id in self.plot_panels: 
    279293                    #remove data from panel 
    280294                    if action_string == 'remove': 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/AnnulusSlicer.py

    r7432acb r83eb5208  
    1 # TODO: the line slicer should listen to all 2DREFRESH events, get the data and slice it 
    2 #      before pushing a new 1D data update. 
    3  
    4 # 
    5 # TODO: NEED MAJOR REFACTOR 
    6 # 
    7  
    8 import math 
    9 import wx 
    10 # from copy import deepcopy 
    11 # Debug printout 
    12 from sas.sasgui.guiframe.events import NewPlotEvent 
    13 from sas.sasgui.guiframe.events import StatusEvent 
    14 from sas.sasgui.guiframe.events import SlicerParameterEvent 
    15 from sas.sasgui.guiframe.events import EVT_SLICER_PARS 
     1import numpy 
     2from PyQt4 import QtGui 
     3from PyQt4 import QtCore 
     4 
    165from BaseInteractor import _BaseInteractor 
    176from sas.sasgui.guiframe.dataFitting import Data1D 
    18  
    19 class AnnulusInteractor(_BaseInteractor): 
     7import sas.qtgui.Utilities.GuiUtils as GuiUtils 
     8from sas.qtgui.Utilities.GuiUtils import formatNumber 
     9from sas.qtgui.Plotting.SlicerModel import SlicerModel 
     10 
     11class AnnulusInteractor(_BaseInteractor, SlicerModel): 
    2012    """ 
    2113    Select an annulus through a 2D plot. 
     
    2416    this class is defined by 2 Ringinterators. 
    2517    """ 
    26     def __init__(self, base, axes, color='black', zorder=3): 
     18    def __init__(self, base, axes, item=None, color='black', zorder=3): 
    2719 
    2820        _BaseInteractor.__init__(self, base, axes, color=color) 
     21        SlicerModel.__init__(self) 
     22 
    2923        self.markers = [] 
    3024        self.axes = axes 
    3125        self.base = base 
    32         self.qmax = min(math.fabs(self.base.data2D.xmax), 
    33                         math.fabs(self.base.data2D.xmin))  # must be positive 
     26        self._item = item 
     27        self.qmax = min(numpy.fabs(self.base.data.xmax), 
     28                        numpy.fabs(self.base.data.xmin))  # must be positive 
    3429        self.connect = self.base.connect 
    3530 
    36         # # Number of points on the plot 
     31        # Number of points on the plot 
    3732        self.nbins = 36 
    3833        # Cursor position of Rings (Left(-1) or Right(1)) 
    39         self.xmaxd = self.base.data2D.xmax 
    40         self.xmind = self.base.data2D.xmin 
     34        self.xmaxd = self.base.data.xmax 
     35        self.xmind = self.base.data.xmin 
    4136 
    4237        if (self.xmaxd + self.xmind) > 0: 
     
    4540            self.sign = -1 
    4641        # Inner circle 
    47         self.inner_circle = RingInteractor(self, self.base.subplot, 
     42        self.inner_circle = RingInteractor(self, self.axes, 
    4843                                           zorder=zorder, 
    4944                                           r=self.qmax / 2.0, sign=self.sign) 
    5045        self.inner_circle.qmax = self.qmax 
    51         self.outer_circle = RingInteractor(self, self.base.subplot, 
     46        self.outer_circle = RingInteractor(self, self.axes, 
    5247                                           zorder=zorder + 1, r=self.qmax / 1.8, 
    5348                                           sign=self.sign) 
     
    5651        self._post_data() 
    5752 
    58         # Bind to slice parameter events 
    59         self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS) 
    60  
    61     def _onEVT_SLICER_PARS(self, event): 
    62         """ 
    63         receive an event containing parameters values to reset the slicer 
    64  
    65         :param event: event of type SlicerParameterEvent with params as 
    66             attribute 
    67  
    68         """ 
    69         wx.PostEvent(self.base, 
    70                      StatusEvent(status="AnnulusSlicer._onEVT_SLICER_PARS")) 
    71         event.Skip() 
    72         if event.type == self.__class__.__name__: 
    73             self.set_params(event.params) 
    74             self.base.update() 
     53        self.setModelFromParams() 
    7554 
    7655    def set_layer(self, n): 
     
    9271        self.inner_circle.clear() 
    9372        self.base.connect.clearall() 
    94         self.base.Unbind(EVT_SLICER_PARS) 
    9573 
    9674    def update(self): 
     
    10886        can restore on Esc. 
    10987        """ 
    110         self.base.freeze_axes() 
    11188        self.inner_circle.save(ev) 
    11289        self.outer_circle.save(ev) 
     
    12097        """ 
    12198        # Data to average 
    122         data = self.base.data2D 
    123         # If we have no data, just return 
     99        data = self.base.data 
    124100        if data is None: 
    125101            return 
    126102 
    127103        from sas.sascalc.dataloader.manipulations import Ring 
    128         rmin = min(math.fabs(self.inner_circle.get_radius()), 
    129                    math.fabs(self.outer_circle.get_radius())) 
    130         rmax = max(math.fabs(self.inner_circle.get_radius()), 
    131                    math.fabs(self.outer_circle.get_radius())) 
    132         # if the user does not specify the numbers of points to plot 
     104        rmin = min(numpy.fabs(self.inner_circle.get_radius()), 
     105                   numpy.fabs(self.outer_circle.get_radius())) 
     106        rmax = max(numpy.fabs(self.inner_circle.get_radius()), 
     107                   numpy.fabs(self.outer_circle.get_radius())) 
     108        # If the user does not specify the numbers of points to plot 
    133109        # the default number will be nbins= 36 
    134110        if nbins is None: 
     
    136112        else: 
    137113            self.nbins = nbins 
    138         # # create the data1D Q average of data2D 
     114        # Create the data1D Q average of data2D 
    139115        sect = Ring(r_min=rmin, r_max=rmax, nbins=self.nbins) 
    140         sector = sect(self.base.data2D) 
     116        sector = sect(self.base.data) 
    141117 
    142118        if hasattr(sector, "dxl"): 
     
    148124        else: 
    149125            dxw = None 
    150         new_plot = Data1D(x=(sector.x - math.pi) * 180 / math.pi, 
     126        new_plot = Data1D(x=(sector.x - numpy.pi) * 180 / numpy.pi, 
    151127                          y=sector.y, dy=sector.dy) 
    152128        new_plot.dxl = dxl 
    153129        new_plot.dxw = dxw 
    154         new_plot.name = "AnnulusPhi" + "(" + self.base.data2D.name + ")" 
    155  
    156         new_plot.source = self.base.data2D.source 
    157         # new_plot.info=self.base.data2D.info 
     130        new_plot.name = "AnnulusPhi" + "(" + self.base.data.name + ")" 
     131        new_plot.title = "AnnulusPhi" + "(" + self.base.data.name + ")" 
     132 
     133        new_plot.source = self.base.data.source 
    158134        new_plot.interactive = True 
    159         new_plot.detector = self.base.data2D.detector 
     135        new_plot.detector = self.base.data.detector 
    160136        # If the data file does not tell us what the axes are, just assume... 
    161137        new_plot.xaxis("\\rm{\phi}", 'degrees') 
    162138        new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}") 
    163139        if hasattr(data, "scale") and data.scale == 'linear' and \ 
    164                 self.base.data2D.name.count("Residuals") > 0: 
     140                self.base.data.name.count("Residuals") > 0: 
    165141            new_plot.ytransform = 'y' 
    166142            new_plot.yaxis("\\rm{Residuals} ", "/") 
    167143 
    168         new_plot.group_id = "AnnulusPhi" + self.base.data2D.name 
    169         new_plot.id = "AnnulusPhi" + self.base.data2D.name 
     144        new_plot.group_id = "AnnulusPhi" + self.base.data.name 
     145        new_plot.id = "AnnulusPhi" + self.base.data.name 
    170146        new_plot.is_data = True 
    171147        new_plot.xtransform = "x" 
    172148        new_plot.ytransform = "y" 
    173         self.base.parent.update_theory(data_id=data.id, theory=new_plot) 
    174         wx.PostEvent(self.base.parent, NewPlotEvent(plot=new_plot, title="AnnulusPhi")) 
     149        variant_plot = QtCore.QVariant(new_plot) 
     150        GuiUtils.updateModelItemWithPlot(self._item, variant_plot, new_plot.id) 
     151        self.base.manager.communicator.plotUpdateSignal.emit([new_plot]) 
     152 
     153        if self.update_model: 
     154            self.setModelFromParams() 
     155        self.draw() 
     156 
     157    def validate(self, param_name, param_value): 
     158        """ 
     159        Test the proposed new value "value" for row "row" of parameters 
     160        """ 
     161        MIN_DIFFERENCE = 0.01 
     162        isValid = True 
     163 
     164        if param_name == 'inner_radius': 
     165            # First, check the closeness 
     166            if numpy.fabs(param_value - self.getParams()['outer_radius']) < MIN_DIFFERENCE: 
     167                print("Inner and outer radii too close. Please adjust.") 
     168                isValid = False 
     169            elif param_value > self.qmax: 
     170                print("Inner radius exceeds maximum range. Please adjust.") 
     171                isValid = False 
     172        elif param_name == 'outer_radius': 
     173            # First, check the closeness 
     174            if numpy.fabs(param_value - self.getParams()['inner_radius']) < MIN_DIFFERENCE: 
     175                print("Inner and outer radii too close. Please adjust.") 
     176                isValid = False 
     177            elif param_value > self.qmax: 
     178                print("Outer radius exceeds maximum range. Please adjust.") 
     179                isValid = False 
     180        elif param_name == 'nbins': 
     181            # Can't be 0 
     182            if param_value < 1: 
     183                print("Number of bins cannot be less than or equal to 0. Please adjust.") 
     184                isValid = False 
     185 
     186        return isValid 
    175187 
    176188    def moveend(self, ev): 
    177189        """ 
    178190        Called when any dragging motion ends. 
    179         Post an event (type =SlicerParameterEvent) 
    180         to plotter 2D with a copy  slicer parameters 
    181         Call  _post_data method 
    182         """ 
    183         self.base.thaw_axes() 
    184         # Post parameters to plotter 2D 
    185         event = SlicerParameterEvent() 
    186         event.type = self.__class__.__name__ 
    187         event.params = self.get_params() 
    188         wx.PostEvent(self.base, event) 
     191        Redraw the plot with new parameters. 
     192        """ 
     193        self._post_data(self.nbins) 
    189194 
    190195    def restore(self): 
     
    204209        pass 
    205210 
    206     def get_params(self): 
     211    def getParams(self): 
    207212        """ 
    208213        Store a copy of values of parameters of the slicer into a dictionary. 
    209  
    210214        :return params: the dictionary created 
    211  
    212215        """ 
    213216        params = {} 
    214         params["inner_radius"] = math.fabs(self.inner_circle._inner_mouse_x) 
    215         params["outer_radius"] = math.fabs(self.outer_circle._inner_mouse_x) 
     217        params["inner_radius"] = numpy.fabs(self.inner_circle._inner_mouse_x) 
     218        params["outer_radius"] = numpy.fabs(self.outer_circle._inner_mouse_x) 
    216219        params["nbins"] = self.nbins 
    217220        return params 
    218221 
    219     def set_params(self, params): 
     222    def setParams(self, params): 
    220223        """ 
    221224        Receive a dictionary and reset the slicer with values contained 
     
    224227        :param params: a dictionary containing name of slicer parameters and 
    225228            values the user assigned to the slicer. 
    226  
    227         """ 
    228         inner = math.fabs(params["inner_radius"]) 
    229         outer = math.fabs(params["outer_radius"]) 
     229        """ 
     230        inner = numpy.fabs(params["inner_radius"]) 
     231        outer = numpy.fabs(params["outer_radius"]) 
    230232        self.nbins = int(params["nbins"]) 
    231         # # Update the picture 
     233        # Update the picture 
    232234        self.inner_circle.set_cursor(inner, self.inner_circle._inner_mouse_y) 
    233235        self.outer_circle.set_cursor(outer, self.outer_circle._inner_mouse_y) 
    234         # # Post the data given the nbins entered by the user 
     236        # Post the data given the nbins entered by the user 
    235237        self._post_data(self.nbins) 
    236  
    237     def freeze_axes(self): 
    238         """ 
    239         """ 
    240         self.base.freeze_axes() 
    241  
    242     def thaw_axes(self): 
    243         """ 
    244         """ 
    245         self.base.thaw_axes() 
    246238 
    247239    def draw(self): 
     
    278270        self.sign = sign 
    279271        # # Create a marker 
    280         try: 
    281             # Inner circle marker 
    282             x_value = [self.sign * math.fabs(self._inner_mouse_x)] 
    283             self.inner_marker = self.axes.plot(x_value, [0], linestyle='', 
    284                                                marker='s', markersize=10, 
    285                                                color=self.color, alpha=0.6, 
    286                                                pickradius=5, label="pick", 
    287                                                zorder=zorder, 
    288                                                visible=True)[0] 
    289         except: 
    290             x_value = [self.sign * math.fabs(self._inner_mouse_x)] 
    291             self.inner_marker = self.axes.plot(x_value, [0], linestyle='', 
    292                                                marker='s', markersize=10, 
    293                                                color=self.color, alpha=0.6, 
    294                                                label="pick", 
    295                                                visible=True)[0] 
    296             message = "\nTHIS PROTOTYPE NEEDS THE LATEST" 
    297             message += " VERSION OF MATPLOTLIB\n" 
    298             message += "Get the SVN version that is at " 
    299             message += " least as recent as June 1, 2007" 
    300  
    301             owner = self.base.base.parent 
    302             wx.PostEvent(owner, StatusEvent(status="AnnulusSlicer: %s" % message)) 
    303  
     272        # Inner circle marker 
     273        x_value = [self.sign * numpy.fabs(self._inner_mouse_x)] 
     274        self.inner_marker = self.axes.plot(x_value, [0], linestyle='', 
     275                                           marker='s', markersize=10, 
     276                                           color=self.color, alpha=0.6, 
     277                                           pickradius=5, label="pick", 
     278                                           zorder=zorder, 
     279                                           visible=True)[0] 
    304280        # Draw a circle 
    305281        [self.inner_circle] = self.axes.plot([], [], linestyle='-', marker='', color=self.color) 
    306         # the number of points that make the ring line 
     282        # The number of points that make the ring line 
    307283        self.npts = 40 
    308284 
     
    325301        """ 
    326302        self.clear_markers() 
    327         try: 
    328             self.inner_marker.remove() 
    329             self.inner_circle.remove() 
    330         except: 
    331             # Old version of matplotlib 
    332             for item in range(len(self.axes.lines)): 
    333                 del self.axes.lines[0] 
     303        self.inner_marker.remove() 
     304        self.inner_circle.remove() 
    334305 
    335306    def get_radius(self): 
     
    347318        y = [] 
    348319        for i in range(self.npts): 
    349             phi = 2.0 * math.pi / (self.npts - 1) * i 
    350  
    351             xval = 1.0 * self._inner_mouse_x * math.cos(phi) 
    352             yval = 1.0 * self._inner_mouse_x * math.sin(phi) 
     320            phi = 2.0 * numpy.pi / (self.npts - 1) * i 
     321 
     322            xval = 1.0 * self._inner_mouse_x * numpy.cos(phi) 
     323            yval = 1.0 * self._inner_mouse_x * numpy.sin(phi) 
    353324 
    354325            x.append(xval) 
    355326            y.append(yval) 
    356327 
    357         self.inner_marker.set(xdata=[self.sign * math.fabs(self._inner_mouse_x)], 
     328        self.inner_marker.set(xdata=[self.sign * numpy.fabs(self._inner_mouse_x)], 
    358329                              ydata=[0]) 
    359330        self.inner_circle.set_data(x, y) 
     
    366337        self._inner_save_x = self._inner_mouse_x 
    367338        self._inner_save_y = self._inner_mouse_y 
    368         self.base.freeze_axes() 
    369339 
    370340    def moveend(self, ev): 
     
    396366        self.update() 
    397367 
    398  
    399     def get_params(self): 
     368    def getParams(self): 
    400369        """ 
    401370        Store a copy of values of parameters of the slicer into a dictionary. 
    402  
    403371        :return params: the dictionary created 
    404  
    405372        """ 
    406373        params = {} 
    407         params["radius"] = math.fabs(self._inner_mouse_x) 
     374        params["radius"] = numpy.fabs(self._inner_mouse_x) 
    408375        return params 
    409376 
    410     def set_params(self, params): 
     377    def setParams(self, params): 
    411378        """ 
    412379        Receive a dictionary and reset the slicer with values contained 
     
    435402        self.base = base 
    436403        self.is_inside = side 
    437         self.qmax = min(math.fabs(self.base.data.xmax), 
    438                         math.fabs(self.base.data.xmin))  # must be positive 
     404        self.qmax = min(numpy.fabs(self.base.data.xmax), 
     405                        numpy.fabs(self.base.data.xmin))  # must be positive 
    439406        self.connect = self.base.connect 
    440407 
     
    448415            self.sign = -1 
    449416        # Inner circle 
    450         self.outer_circle = RingInteractor(self, self.base.subplot, 'blue', 
     417        self.outer_circle = RingInteractor(self, self.axes, 'blue', 
    451418                                           zorder=zorder + 1, r=self.qmax / 1.8, 
    452419                                           sign=self.sign) 
     
    455422        self._post_data() 
    456423 
    457         # Bind to slice parameter events 
    458         # self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS) 
    459  
    460     def _onEVT_SLICER_PARS(self, event): 
    461         """ 
    462         receive an event containing parameters values to reset the slicer 
    463  
    464         :param event: event of type SlicerParameterEvent with params as 
    465             attribute 
    466         """ 
    467         wx.PostEvent(self.base, 
    468                      StatusEvent(status="AnnulusSlicer._onEVT_SLICER_PARS")) 
    469         event.Skip() 
    470         if event.type == self.__class__.__name__: 
    471             self.set_params(event.params) 
    472             self.base.update() 
    473  
    474424    def set_layer(self, n): 
    475425        """ 
    476426        Allow adding plot to the same panel 
    477  
    478427        :param n: the number of layer 
    479  
    480428        """ 
    481429        self.layernum = n 
     
    489437        self.outer_circle.clear() 
    490438        self.base.connect.clearall() 
    491         # self.base.Unbind(EVT_SLICER_PARS) 
    492439 
    493440    def update(self): 
     
    498445        # Update locations 
    499446        self.outer_circle.update() 
    500         # if self.is_inside is not None: 
     447        self._post_data() 
    501448        out = self._post_data() 
    502449        return out 
     
    507454        can restore on Esc. 
    508455        """ 
    509         self.base.freeze_axes() 
    510456        self.outer_circle.save(ev) 
    511457 
     
    527473 
    528474        rmin = 0 
    529         rmax = math.fabs(self.outer_circle.get_radius()) 
    530  
    531         # # create the data1D Q average of data2D 
     475        rmax = numpy.fabs(self.outer_circle.get_radius()) 
     476 
     477        # Create the data1D Q average of data2D 
    532478        mask = Ringcut(r_min=rmin, r_max=rmax) 
    533479 
     
    536482        else: 
    537483            out = (mask(data)) 
    538         # self.base.data.mask=out 
    539484        return out 
    540485 
     
    566511        pass 
    567512 
    568     def get_params(self): 
     513    def getParams(self): 
    569514        """ 
    570515        Store a copy of values of parameters of the slicer into a dictionary. 
     
    574519        """ 
    575520        params = {} 
    576         params["outer_radius"] = math.fabs(self.outer_circle._inner_mouse_x) 
     521        params["outer_radius"] = numpy.fabs(self.outer_circle._inner_mouse_x) 
    577522        return params 
    578523 
    579     def set_params(self, params): 
     524    def setParams(self, params): 
    580525        """ 
    581526        Receive a dictionary and reset the slicer with values contained 
     
    585530            values the user assigned to the slicer. 
    586531        """ 
    587         outer = math.fabs(params["outer_radius"]) 
    588         # # Update the picture 
     532        outer = numpy.fabs(params["outer_radius"]) 
     533        # Update the picture 
    589534        self.outer_circle.set_cursor(outer, self.outer_circle._inner_mouse_y) 
    590         # # Post the data given the nbins entered by the user 
     535        # Post the data given the nbins entered by the user 
    591536        self._post_data() 
    592  
    593     def freeze_axes(self): 
    594         self.base.freeze_axes() 
    595  
    596     def thaw_axes(self): 
    597         self.base.thaw_axes() 
    598537 
    599538    def draw(self): 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/AzimutSlicer.py

    rd85c194 r161713c  
    182182                     NewPlotEvent(plot=new_plot, title=str(new_sector.__name__))) 
    183183 
     184 
     185    def validate(self, param_name, param_value): 
     186        """ 
     187        Test the proposed new value "value" for row "row" of parameters 
     188        """ 
     189        # Here, always return true 
     190        return True 
     191 
    184192    def moveend(self, ev): 
    185193        #TODO: why is this empty? 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter1D.py

    r7432acb rc416a17  
    1  
    21################################################################################ 
    32# This software was developed by the University of Tennessee as part of the 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/SectorSlicer.py

    r8de66b6 rc416a17  
    22    Sector interactor 
    33""" 
    4 import math 
    5 import wx 
     4import numpy 
     5from PyQt4 import QtGui 
     6from PyQt4 import QtCore 
     7 
    68from BaseInteractor import _BaseInteractor 
    7 from sas.sasgui.guiframe.events import NewPlotEvent 
    8 from sas.sasgui.guiframe.events import StatusEvent 
    9 from sas.sasgui.guiframe.events import SlicerParameterEvent 
    10 from sas.sasgui.guiframe.events import EVT_SLICER_PARS 
    119from sas.sasgui.guiframe.dataFitting import Data1D 
    12  
    13  
    14 class SectorInteractor(_BaseInteractor): 
     10import sas.qtgui.Utilities.GuiUtils as GuiUtils 
     11from sas.qtgui.Plotting.SlicerModel import SlicerModel 
     12 
     13MIN_PHI = 0.05 
     14 
     15class SectorInteractor(_BaseInteractor, SlicerModel): 
    1516    """ 
    1617    Draw a sector slicer.Allow to performQ averaging on data 2D 
    1718    """ 
    18     def __init__(self, base, axes, color='black', zorder=3): 
     19    def __init__(self, base, axes, item=None, color='black', zorder=3): 
    1920 
    2021        _BaseInteractor.__init__(self, base, axes, color=color) 
    21         ## Class initialization 
     22        SlicerModel.__init__(self) 
     23        # Class initialization 
    2224        self.markers = [] 
    2325        self.axes = axes 
    24         ## connect the plot to event 
     26        self._item = item 
     27        # Connect the plot to event 
    2528        self.connect = self.base.connect 
    2629 
    27         ## compute qmax limit to reset the graph 
    28         x = math.pow(max(self.base.data2D.xmax, 
    29                          math.fabs(self.base.data2D.xmin)), 2) 
    30         y = math.pow(max(self.base.data2D.ymax, 
    31                          math.fabs(self.base.data2D.ymin)), 2) 
    32         self.qmax = math.sqrt(x + y) 
    33         ## Number of points on the plot 
     30        # Compute qmax limit to reset the graph 
     31        x = numpy.power(max(self.base.data.xmax, 
     32                         numpy.fabs(self.base.data.xmin)), 2) 
     33        y = numpy.power(max(self.base.data.ymax, 
     34                         numpy.fabs(self.base.data.ymin)), 2) 
     35        self.qmax = numpy.sqrt(x + y) 
     36        # Number of points on the plot 
    3437        self.nbins = 20 
    35         ## Angle of the middle line 
    36         self.theta2 = math.pi / 3 
    37         ## Absolute value of the Angle between the middle line and any side line 
    38         self.phi = math.pi / 12 
    39         # Binning base for log/lin binning 
    40         self.bin_base = 0 
    41         ## Middle line 
    42         self.main_line = LineInteractor(self, self.base.subplot, color='blue', 
     38        # Angle of the middle line 
     39        self.theta2 = numpy.pi / 3 
     40        # Absolute value of the Angle between the middle line and any side line 
     41        self.phi = numpy.pi / 12 
     42        # Middle line 
     43        self.main_line = LineInteractor(self, self.axes, color='blue', 
    4344                                        zorder=zorder, r=self.qmax, 
    4445                                        theta=self.theta2) 
    4546        self.main_line.qmax = self.qmax 
    46         ## Right Side line 
    47         self.right_line = SideInteractor(self, self.base.subplot, color='black', 
     47        # Right Side line 
     48        self.right_line = SideInteractor(self, self.axes, color='black', 
    4849                                         zorder=zorder, r=self.qmax, 
    4950                                         phi=-1 * self.phi, theta2=self.theta2) 
    5051        self.right_line.qmax = self.qmax 
    51         ## Left Side line 
    52         self.left_line = SideInteractor(self, self.base.subplot, color='black', 
     52        # Left Side line 
     53        self.left_line = SideInteractor(self, self.axes, color='black', 
    5354                                        zorder=zorder, r=self.qmax, 
    5455                                        phi=self.phi, theta2=self.theta2) 
    5556        self.left_line.qmax = self.qmax 
    56         ## draw the sector 
     57        # draw the sector 
    5758        self.update() 
    5859        self._post_data() 
    59         ## Bind to slice parameter events 
    60         self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS) 
    61  
    62     def _onEVT_SLICER_PARS(self, event): 
    63         """ 
    64         receive an event containing parameters values to reset the slicer 
    65  
    66         :param event: event of type SlicerParameterEvent with params as 
    67         attribute 
    68  
    69         """ 
    70         wx.PostEvent(self.base.parent, 
    71                      StatusEvent(status="SectorSlicer._onEVT_SLICER_PARS")) 
    72         event.Skip() 
    73         if event.type == self.__class__.__name__: 
    74             self.set_params(event.params) 
    75             self.base.update() 
     60        self.setModelFromParams() 
    7661 
    7762    def set_layer(self, n): 
    7863        """ 
    7964         Allow adding plot to the same panel 
    80  
    8165        :param n: the number of layer 
    82  
    8366        """ 
    8467        self.layernum = n 
     
    9477        self.right_line.clear() 
    9578        self.base.connect.clearall() 
    96         self.base.Unbind(EVT_SLICER_PARS) 
    9779 
    9880    def update(self): 
     
    10284        """ 
    10385        # Update locations 
    104         ## Check if the middle line was dragged and 
    105         #update the picture accordingly 
     86        # Check if the middle line was dragged and 
     87        # update the picture accordingly 
    10688        if self.main_line.has_move: 
    10789            self.main_line.update() 
     
    11092            self.left_line.update(delta=self.left_line.phi / 2, 
    11193                                  mline=self.main_line.theta) 
    112         ## Check if the left side has moved and update the slicer accordingly 
     94        # Check if the left side has moved and update the slicer accordingly 
    11395        if self.left_line.has_move: 
    11496            self.main_line.update() 
     
    118100                                   mline=self.main_line, side=True, 
    119101                                   left=False, right=True) 
    120         ## Check if the right side line has moved and 
    121         #update the slicer accordingly 
     102        # Check if the right side line has moved and update the slicer accordingly 
    122103        if self.right_line.has_move: 
    123104            self.main_line.update() 
     
    132113        can restore on Esc. 
    133114        """ 
    134         self.base.freeze_axes() 
    135115        self.main_line.save(ev) 
    136116        self.right_line.save(ev) 
     
    143123        :param nbins: the number of point to plot for the average 1D data 
    144124        """ 
    145         ## get the data2D to average 
    146         data = self.base.data2D 
     125        # Get the data2D to average 
     126        data = self.base.data 
    147127        # If we have no data, just return 
    148         if data is None: 
     128        if data == None: 
    149129            return 
    150         ## Averaging 
     130        # Averaging 
    151131        from sas.sascalc.dataloader.manipulations import SectorQ 
    152132        radius = self.qmax 
    153133        phimin = -self.left_line.phi + self.main_line.theta 
    154134        phimax = self.left_line.phi + self.main_line.theta 
    155         bin_base = self.bin_base 
    156         if nbins is None: 
     135        if nbins == None: 
    157136            nbins = 20 
    158137        sect = SectorQ(r_min=0.0, r_max=radius, 
    159                        phi_min=phimin + math.pi, 
    160                        phi_max=phimax + math.pi, nbins=nbins, base=bin_base) 
    161  
    162         sector = sect(self.base.data2D) 
    163         ##Create 1D data resulting from average 
     138                       phi_min=phimin + numpy.pi, 
     139                       phi_max=phimax + numpy.pi, nbins=nbins) 
     140 
     141        sector = sect(self.base.data) 
     142        # Create 1D data resulting from average 
    164143 
    165144        if hasattr(sector, "dxl"): 
     
    174153        new_plot.dxl = dxl 
    175154        new_plot.dxw = dxw 
    176         new_plot.name = "SectorQ" + "(" + self.base.data2D.name + ")" 
    177         new_plot.source = self.base.data2D.source 
    178         #new_plot.info=self.base.data2D.info 
     155        new_plot.name = "SectorQ" + "(" + self.base.data.name + ")" 
     156        new_plot.title = "SectorQ" + "(" + self.base.data.name + ")" 
     157        new_plot.source = self.base.data.source 
    179158        new_plot.interactive = True 
    180         new_plot.detector = self.base.data2D.detector 
    181         ## If the data file does not tell us what the axes are, just assume... 
     159        new_plot.detector = self.base.data.detector 
     160        # If the data file does not tell us what the axes are, just assume them. 
    182161        new_plot.xaxis("\\rm{Q}", "A^{-1}") 
    183162        new_plot.yaxis("\\rm{Intensity}", "cm^{-1}") 
    184163        if hasattr(data, "scale") and data.scale == 'linear' and \ 
    185                 self.base.data2D.name.count("Residuals") > 0: 
     164                self.base.data.name.count("Residuals") > 0: 
    186165            new_plot.ytransform = 'y' 
    187166            new_plot.yaxis("\\rm{Residuals} ", "/") 
    188167 
    189         new_plot.group_id = "2daverage" + self.base.data2D.name 
    190         new_plot.id = "SectorQ" + self.base.data2D.name 
     168        new_plot.group_id = "2daverage" + self.base.data.name 
     169        new_plot.id = "SectorQ" + self.base.data.name 
    191170        new_plot.is_data = True 
    192         self.base.parent.update_theory(data_id=data.id, theory=new_plot) 
    193         wx.PostEvent(self.base.parent, 
    194                      NewPlotEvent(plot=new_plot, title="SectorQ" + self.base.data2D.name)) 
     171        variant_plot = QtCore.QVariant(new_plot) 
     172        GuiUtils.updateModelItemWithPlot(self._item, variant_plot, new_plot.id) 
     173        self.base.manager.communicator.plotUpdateSignal.emit([new_plot]) 
     174 
     175        if self.update_model: 
     176            self.setModelFromParams() 
     177        self.draw() 
     178 
     179    def validate(self, param_name, param_value): 
     180        """ 
     181        Test the proposed new value "value" for row "row" of parameters 
     182        """ 
     183        MIN_DIFFERENCE = 0.01 
     184        isValid = True 
     185 
     186        if param_name == 'Delta_Phi [deg]': 
     187            # First, check the closeness 
     188            if numpy.fabs(param_value) < MIN_DIFFERENCE: 
     189                print("Sector angles too close. Please adjust.") 
     190                isValid = False 
     191        elif param_name == 'nbins': 
     192            # Can't be 0 
     193            if param_value < 1: 
     194                print("Number of bins cannot be less than or equal to 0. Please adjust.") 
     195                isValid = False 
     196        return isValid 
    195197 
    196198    def moveend(self, ev): 
     
    198200        Called a dragging motion ends.Get slicer event 
    199201        """ 
    200         self.base.thaw_axes() 
    201         ## Post parameters 
    202         event = SlicerParameterEvent() 
    203         event.type = self.__class__.__name__ 
    204         event.params = self.get_params() 
    205         ## Send slicer paramers to plotter2D 
    206         wx.PostEvent(self.base, event) 
     202        # Post parameters 
     203        self._post_data(self.nbins) 
    207204 
    208205    def restore(self): 
     
    225222        pass 
    226223 
    227     def get_params(self): 
     224    def getParams(self): 
    228225        """ 
    229226        Store a copy of values of parameters of the slicer into a dictionary. 
    230  
    231227        :return params: the dictionary created 
    232  
    233228        """ 
    234229        params = {} 
    235         ## Always make sure that the left and the right line are at phi 
    236         ## angle of the middle line 
    237         if math.fabs(self.left_line.phi) != math.fabs(self.right_line.phi): 
     230        # Always make sure that the left and the right line are at phi 
     231        # angle of the middle line 
     232        if numpy.fabs(self.left_line.phi) != numpy.fabs(self.right_line.phi): 
    238233            msg = "Phi left and phi right are different" 
    239234            msg += " %f, %f" % (self.left_line.phi, self.right_line.phi) 
    240235            raise ValueError, msg 
    241         params["Phi [deg]"] = self.main_line.theta * 180 / math.pi 
    242         params["Delta_Phi [deg]"] = math.fabs(self.left_line.phi * 180 / math.pi) 
     236        params["Phi [deg]"] = self.main_line.theta * 180 / numpy.pi 
     237        params["Delta_Phi [deg]"] = numpy.fabs(self.left_line.phi * 180 / numpy.pi) 
    243238        params["nbins"] = self.nbins 
    244         params["binning base"] = self.bin_base 
    245239        return params 
    246240 
    247     def set_params(self, params): 
     241    def setParams(self, params): 
    248242        """ 
    249243        Receive a dictionary and reset the slicer with values contained 
     
    253247            values the user assigned to the slicer. 
    254248        """ 
    255         main = params["Phi [deg]"] * math.pi / 180 
    256         phi = math.fabs(params["Delta_Phi [deg]"] * math.pi / 180) 
     249        main = params["Phi [deg]"] * numpy.pi / 180 
     250        phi = numpy.fabs(params["Delta_Phi [deg]"] * numpy.pi / 180) 
     251 
     252        # phi should not be too close. 
     253        if numpy.fabs(phi) < MIN_PHI: 
     254            phi = MIN_PHI 
     255            params["Delta_Phi [deg]"] = MIN_PHI 
     256 
    257257        self.nbins = int(params["nbins"]) 
    258         self.bin_base = params["binning base"] 
    259258        self.main_line.theta = main 
    260         ## Reset the slicer parameters 
     259        # Reset the slicer parameters 
    261260        self.main_line.update() 
    262261        self.right_line.update(phi=phi, delta=None, mline=self.main_line, 
     
    264263        self.left_line.update(phi=phi, delta=None, 
    265264                              mline=self.main_line, side=True) 
    266         ## post the new corresponding data 
     265        # Post the new corresponding data 
    267266        self._post_data(nbins=self.nbins) 
    268267 
    269     def freeze_axes(self): 
    270         """ 
    271         """ 
    272         self.base.freeze_axes() 
    273  
    274     def thaw_axes(self): 
    275         """ 
    276         """ 
    277         self.base.thaw_axes() 
    278  
    279268    def draw(self): 
    280269        """ 
     270        Redraw canvas 
    281271        """ 
    282272        self.base.draw() 
     
    292282    """ 
    293283    def __init__(self, base, axes, color='black', zorder=5, r=1.0, 
    294                  phi=math.pi / 4, theta2=math.pi / 3): 
     284                 phi=numpy.pi / 4, theta2=numpy.pi / 3): 
    295285        """ 
    296286        """ 
    297287        _BaseInteractor.__init__(self, base, axes, color=color) 
    298         ## Initialize the class 
     288        # Initialize the class 
    299289        self.markers = [] 
    300290        self.axes = axes 
    301         ## compute the value of the angle between the current line and 
    302         ## the x-axis 
     291        # compute the value of the angle between the current line and 
     292        # the x-axis 
    303293        self.save_theta = theta2 + phi 
    304294        self.theta = theta2 + phi 
    305         ## the value of the middle line angle with respect to the x-axis 
     295        # the value of the middle line angle with respect to the x-axis 
    306296        self.theta2 = theta2 
    307         ## Radius to find polar coordinates this line's endpoints 
     297        # Radius to find polar coordinates this line's endpoints 
    308298        self.radius = r 
    309         ## phi is the phase between the current line and the middle line 
     299        # phi is the phase between the current line and the middle line 
    310300        self.phi = phi 
    311         ## End points polar coordinates 
    312         x1 = self.radius * math.cos(self.theta) 
    313         y1 = self.radius * math.sin(self.theta) 
    314         x2 = -1 * self.radius * math.cos(self.theta) 
    315         y2 = -1 * self.radius * math.sin(self.theta) 
    316         ## defining a new marker 
     301        # End points polar coordinates 
     302        x1 = self.radius * numpy.cos(self.theta) 
     303        y1 = self.radius * numpy.sin(self.theta) 
     304        x2 = -1 * self.radius * numpy.cos(self.theta) 
     305        y2 = -1 * self.radius * numpy.sin(self.theta) 
     306        # Defining a new marker 
    317307        self.inner_marker = self.axes.plot([x1 / 2.5], [y1 / 2.5], linestyle='', 
    318308                                           marker='s', markersize=10, 
     
    321311                                           zorder=zorder, visible=True)[0] 
    322312 
    323         ## Defining the current line 
     313        # Defining the current line 
    324314        self.line = self.axes.plot([x1, x2], [y1, y2], 
    325315                                   linestyle='-', marker='', 
    326316                                   color=self.color, visible=True)[0] 
    327         ## Flag to differentiate the left line from the right line motion 
     317        # Flag to differentiate the left line from the right line motion 
    328318        self.left_moving = False 
    329         ## Flag to define a motion 
     319        # Flag to define a motion 
    330320        self.has_move = False 
    331         ## connecting markers and draw the picture 
     321        # connecting markers and draw the picture 
    332322        self.connect_markers([self.inner_marker, self.line]) 
    333323 
     
    335325        """ 
    336326        Allow adding plot to the same panel 
    337  
    338327        :param n: the number of layer 
    339  
    340328        """ 
    341329        self.layernum = n 
     
    364352 
    365353        """ 
    366         #print "update left or right ", self.has_move 
    367354        self.left_moving = left 
    368355        theta3 = 0 
    369         if phi is not None: 
     356        if phi != None: 
    370357            self.phi = phi 
    371         if delta is None: 
     358        if delta == None: 
    372359            delta = 0 
    373360        if  right: 
    374             self.phi = -1 * math.fabs(self.phi) 
     361            self.phi = -1 * numpy.fabs(self.phi) 
    375362            #delta=-delta 
    376363        else: 
    377             self.phi = math.fabs(self.phi) 
     364            self.phi = numpy.fabs(self.phi) 
    378365        if side: 
    379366            self.theta = mline.theta + self.phi 
    380367 
    381         if mline is not None: 
     368        if mline != None: 
    382369            if delta != 0: 
    383370                self.theta2 = mline + delta 
     
    388375        else: 
    389376            theta3 = self.theta2 + delta 
    390         x1 = self.radius * math.cos(theta3) 
    391         y1 = self.radius * math.sin(theta3) 
    392         x2 = -1 * self.radius * math.cos(theta3) 
    393         y2 = -1 * self.radius * math.sin(theta3) 
     377        x1 = self.radius * numpy.cos(theta3) 
     378        y1 = self.radius * numpy.sin(theta3) 
     379        x2 = -1 * self.radius * numpy.cos(theta3) 
     380        y2 = -1 * self.radius * numpy.sin(theta3) 
    394381        self.inner_marker.set(xdata=[x1 / 2.5], ydata=[y1 / 2.5]) 
    395382        self.line.set(xdata=[x1, x2], ydata=[y1, y2]) 
     
    401388        """ 
    402389        self.save_theta = self.theta 
    403         self.base.freeze_axes() 
    404390 
    405391    def moveend(self, ev): 
     
    419405        Process move to a new position, making sure that the move is allowed. 
    420406        """ 
    421         self.theta = math.atan2(y, x) 
     407        self.theta = numpy.arctan2(y, x) 
    422408        self.has_move = True 
    423         #ToDo: Simplify below 
    424409        if not self.left_moving: 
    425410            if  self.theta2 - self.theta <= 0 and self.theta2 > 0: 
     
    431416                return 
    432417            elif  self.theta2 < 0 and self.theta > 0 and \ 
    433                 (self.theta2 + 2 * math.pi - self.theta) >= math.pi / 2: 
     418                (self.theta2 + 2 * numpy.pi - self.theta) >= numpy.pi / 2: 
    434419                self.restore() 
    435420                return 
    436421            elif  self.theta2 < 0 and self.theta < 0 and \ 
    437                 (self.theta2 - self.theta) >= math.pi / 2: 
    438                 self.restore() 
    439                 return 
    440             elif self.theta2 > 0 and (self.theta2 - self.theta >= math.pi / 2 or \ 
    441                 (self.theta2 - self.theta >= math.pi / 2)): 
     422                (self.theta2 - self.theta) >= numpy.pi / 2: 
     423                self.restore() 
     424                return 
     425            elif self.theta2 > 0 and (self.theta2 - self.theta >= numpy.pi / 2 or \ 
     426                (self.theta2 - self.theta >= numpy.pi / 2)): 
    442427                self.restore() 
    443428                return 
    444429        else: 
    445             if  self.theta < 0 and (self.theta + math.pi * 2 - self.theta2) <= 0: 
     430            if  self.theta < 0 and (self.theta + numpy.pi * 2 - self.theta2) <= 0: 
    446431                self.restore() 
    447432                return 
     
    452437                self.restore() 
    453438                return 
    454             elif self.theta - self.theta2 >= math.pi / 2 or  \ 
    455                 ((self.theta + math.pi * 2 - self.theta2) >= math.pi / 2 and \ 
     439            elif self.theta - self.theta2 >= numpy.pi / 2 or  \ 
     440                ((self.theta + numpy.pi * 2 - self.theta2) >= numpy.pi / 2 and \ 
    456441                 self.theta < 0 and self.theta2 > 0): 
    457442                self.restore() 
    458443                return 
    459  
    460         self.phi = math.fabs(self.theta2 - self.theta) 
    461         if self.phi > math.pi: 
    462             self.phi = 2 * math.pi - math.fabs(self.theta2 - self.theta) 
     444        self.phi = numpy.fabs(self.theta2 - self.theta) 
     445        if self.phi > numpy.pi: 
     446            self.phi = 2 * numpy.pi - numpy.fabs(self.theta2 - self.theta) 
    463447        self.base.base.update() 
    464448 
     
    469453        self.update() 
    470454 
    471     def get_params(self): 
     455    def getParams(self): 
    472456        """ 
    473457        """ 
     
    477461        return params 
    478462 
    479     def set_params(self, params): 
     463    def setParams(self, params): 
    480464        """ 
    481465        """ 
     
    489473    """ 
    490474    def __init__(self, base, axes, color='black', 
    491                  zorder=5, r=1.0, theta=math.pi / 4): 
     475                 zorder=5, r=1.0, theta=numpy.pi / 4): 
    492476        """ 
    493477        """ 
     
    501485        self.scale = 10.0 
    502486        # Inner circle 
    503         x1 = self.radius * math.cos(self.theta) 
    504         y1 = self.radius * math.sin(self.theta) 
    505         x2 = -1 * self.radius * math.cos(self.theta) 
    506         y2 = -1 * self.radius * math.sin(self.theta) 
     487        x1 = self.radius * numpy.cos(self.theta) 
     488        y1 = self.radius * numpy.sin(self.theta) 
     489        x2 = -1 * self.radius * numpy.cos(self.theta) 
     490        y2 = -1 * self.radius * numpy.sin(self.theta) 
    507491        # Inner circle marker 
    508492        self.inner_marker = self.axes.plot([x1 / 2.5], [y1 / 2.5], linestyle='', 
     
    543527        """ 
    544528 
    545         if theta is not None: 
     529        if theta != None: 
    546530            self.theta = theta 
    547         x1 = self.radius * math.cos(self.theta) 
    548         y1 = self.radius * math.sin(self.theta) 
    549         x2 = -1 * self.radius * math.cos(self.theta) 
    550         y2 = -1 * self.radius * math.sin(self.theta) 
     531        x1 = self.radius * numpy.cos(self.theta) 
     532        y1 = self.radius * numpy.sin(self.theta) 
     533        x2 = -1 * self.radius * numpy.cos(self.theta) 
     534        y2 = -1 * self.radius * numpy.sin(self.theta) 
    551535 
    552536        self.inner_marker.set(xdata=[x1 / 2.5], ydata=[y1 / 2.5]) 
     
    559543        """ 
    560544        self.save_theta = self.theta 
    561         self.base.freeze_axes() 
    562545 
    563546    def moveend(self, ev): 
     
    577560        Process move to a new position, making sure that the move is allowed. 
    578561        """ 
    579         self.theta = math.atan2(y, x) 
     562        self.theta = numpy.arctan2(y, x) 
    580563        self.has_move = True 
    581564        self.base.base.update() 
     
    587570        self.update() 
    588571 
    589     def get_params(self): 
     572    def getParams(self): 
    590573        """ 
    591574        """ 
     
    595578        return params 
    596579 
    597     def set_params(self, params): 
     580    def setParams(self, params): 
    598581        """ 
    599582        """ 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/boxSlicer.py

    r7432acb r83eb5208  
    1 import wx 
    2 import math 
    3 import numpy as np 
    4 from sas.sasgui.guiframe.events import NewPlotEvent 
    5 from sas.sasgui.guiframe.events import StatusEvent 
    6 from sas.sasgui.guiframe.events import SlicerParameterEvent 
    7 from sas.sasgui.guiframe.events import EVT_SLICER_PARS 
     1import numpy 
     2from PyQt4 import QtGui 
     3from PyQt4 import QtCore 
     4 
    85from BaseInteractor import _BaseInteractor 
    96from sas.sasgui.guiframe.dataFitting import Data1D 
    10  
    11  
    12 class BoxInteractor(_BaseInteractor): 
     7import sas.qtgui.Utilities.GuiUtils as GuiUtils 
     8from sas.qtgui.Plotting.SlicerModel import SlicerModel 
     9 
     10 
     11class BoxInteractor(_BaseInteractor, SlicerModel): 
    1312    """ 
    1413    BoxInteractor define a rectangle that return data1D average of Data2D 
    1514    in a rectangle area defined by -x, x ,y, -y 
    1615    """ 
    17     def __init__(self, base, axes, color='black', zorder=3): 
     16    def __init__(self, base, axes, item=None, color='black', zorder=3): 
    1817        _BaseInteractor.__init__(self, base, axes, color=color) 
    19         # # Class initialization 
     18        SlicerModel.__init__(self) 
     19        # Class initialization 
    2020        self.markers = [] 
    2121        self.axes = axes 
    22         # #connecting artist 
     22        self._item = item 
     23        #connecting artist 
    2324        self.connect = self.base.connect 
    24         # # which direction is the preferred interaction direction 
     25        # which direction is the preferred interaction direction 
    2526        self.direction = None 
    26         # # determine x y  values 
    27         self.x = 0.5 * min(math.fabs(self.base.data2D.xmax), 
    28                            math.fabs(self.base.data2D.xmin)) 
    29         self.y = 0.5 * min(math.fabs(self.base.data2D.xmax), 
    30                            math.fabs(self.base.data2D.xmin)) 
    31         # # when reach qmax reset the graph 
    32         self.qmax = max(self.base.data2D.xmax, self.base.data2D.xmin, 
    33                         self.base.data2D.ymax, self.base.data2D.ymin) 
    34         # # Number of points on the plot 
     27        # determine x y  values 
     28        self.x = 0.5 * min(numpy.fabs(self.base.data.xmax), 
     29                           numpy.fabs(self.base.data.xmin)) 
     30        self.y = 0.5 * min(numpy.fabs(self.base.data.xmax), 
     31                           numpy.fabs(self.base.data.xmin)) 
     32        # when reach qmax reset the graph 
     33        self.qmax = max(self.base.data.xmax, self.base.data.xmin, 
     34                        self.base.data.ymax, self.base.data.ymin) 
     35        # Number of points on the plot 
    3536        self.nbins = 30 
    36         # # If True, I(|Q|) will be return, otherwise, 
     37        # If True, I(|Q|) will be return, otherwise, 
    3738        # negative q-values are allowed 
    3839        self.fold = True 
    39         # # reference of the current  Slab averaging 
     40        # reference of the current  Slab averaging 
    4041        self.averager = None 
    41         # # Create vertical and horizaontal lines for the rectangle 
     42        # Create vertical and horizaontal lines for the rectangle 
    4243        self.vertical_lines = VerticalLines(self, 
    43                                             self.base.subplot, 
     44                                            self.axes, 
    4445                                            color='blue', 
    4546                                            zorder=zorder, 
     
    4950 
    5051        self.horizontal_lines = HorizontalLines(self, 
    51                                                 self.base.subplot, 
     52                                                self.axes, 
    5253                                                color='green', 
    5354                                                zorder=zorder, 
     
    5556                                                y=self.y) 
    5657        self.horizontal_lines.qmax = self.qmax 
    57         # # draw the rectangle and plost the data 1D resulting 
    58         # # of averaging data2D 
     58        # draw the rectangle and plost the data 1D resulting 
     59        # of averaging data2D 
    5960        self.update() 
    6061        self._post_data() 
    61         # # Bind to slice parameter events 
    62         self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS) 
    63  
    64     def _onEVT_SLICER_PARS(self, event): 
    65         """ 
    66         receive an event containing parameters values to reset the slicer 
    67  
    68         :param event: event of type SlicerParameterEvent with params as 
    69             attribute 
    70         """ 
    71         wx.PostEvent(self.base.parent, 
    72                      StatusEvent(status="BoxSlicer._onEVT_SLICER_PARS")) 
    73         event.Skip() 
    74         if event.type == self.__class__.__name__: 
    75             self.set_params(event.params) 
    76             self.base.update() 
     62        self.setModelFromParams() 
    7763 
    7864    def update_and_post(self): 
     
    10288        self.vertical_lines.clear() 
    10389        self.base.connect.clearall() 
    104         self.base.Unbind(EVT_SLICER_PARS) 
    10590 
    10691    def update(self): 
     
    123108        can restore on Esc. 
    124109        """ 
    125         self.base.freeze_axes() 
    126110        self.vertical_lines.save(ev) 
    127111        self.horizontal_lines.save(ev) 
     
    142126            self.direction = direction 
    143127 
    144         x_min = -1 * math.fabs(self.vertical_lines.x) 
    145         x_max = math.fabs(self.vertical_lines.x) 
    146         y_min = -1 * math.fabs(self.horizontal_lines.y) 
    147         y_max = math.fabs(self.horizontal_lines.y) 
     128        x_min = -1 * numpy.fabs(self.vertical_lines.x) 
     129        x_max = numpy.fabs(self.vertical_lines.x) 
     130        y_min = -1 * numpy.fabs(self.horizontal_lines.y) 
     131        y_max = numpy.fabs(self.horizontal_lines.y) 
    148132 
    149133        if nbins is not None: 
     
    158142                x_low = 0 
    159143            else: 
    160                 x_low = math.fabs(x_min) 
     144                x_low = numpy.fabs(x_min) 
    161145            bin_width = (x_max + x_low) / self.nbins 
    162146        elif self.direction == "Y": 
     
    164148                y_low = 0 
    165149            else: 
    166                 y_low = math.fabs(y_min) 
     150                y_low = numpy.fabs(y_min) 
    167151            bin_width = (y_max + y_low) / self.nbins 
    168152        else: 
     
    173157                            bin_width=bin_width) 
    174158        box.fold = self.fold 
    175         boxavg = box(self.base.data2D) 
     159        boxavg = box(self.base.data) 
    176160        # 3 Create Data1D to plot 
    177161        if hasattr(boxavg, "dxl"): 
     
    187171        new_plot.dxw = dxw 
    188172        new_plot.name = str(self.averager.__name__) + \ 
    189                         "(" + self.base.data2D.name + ")" 
    190         new_plot.source = self.base.data2D.source 
     173                        "(" + self.base.data.name + ")" 
     174        new_plot.title = str(self.averager.__name__) + \ 
     175                        "(" + self.base.data.name + ")" 
     176        new_plot.source = self.base.data.source 
    191177        new_plot.interactive = True 
    192         new_plot.detector = self.base.data2D.detector 
     178        new_plot.detector = self.base.data.detector 
    193179        # # If the data file does not tell us what the axes are, just assume... 
    194180        new_plot.xaxis("\\rm{Q}", "A^{-1}") 
    195181        new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}") 
    196182 
    197         data = self.base.data2D 
     183        data = self.base.data 
    198184        if hasattr(data, "scale") and data.scale == 'linear' and \ 
    199                 self.base.data2D.name.count("Residuals") > 0: 
     185                self.base.data.name.count("Residuals") > 0: 
    200186            new_plot.ytransform = 'y' 
    201187            new_plot.yaxis("\\rm{Residuals} ", "/") 
    202188 
    203         new_plot.group_id = "2daverage" + self.base.data2D.name 
    204         new_plot.id = (self.averager.__name__) + self.base.data2D.name 
     189        new_plot.group_id = "2daverage" + self.base.data.name 
     190        new_plot.id = (self.averager.__name__) + self.base.data.name 
    205191        new_plot.is_data = True 
    206         self.base.parent.update_theory(data_id=self.base.data2D.id, \ 
    207                                        theory=new_plot) 
    208         wx.PostEvent(self.base.parent, 
    209                      NewPlotEvent(plot=new_plot, title=str(self.averager.__name__))) 
     192        variant_plot = QtCore.QVariant(new_plot) 
     193        GuiUtils.updateModelItemWithPlot(self._item, variant_plot, new_plot.id) 
     194 
     195        if self.update_model: 
     196            self.setModelFromParams() 
     197        self.draw() 
    210198 
    211199    def moveend(self, ev): 
     
    215203        corresponding to the new average 
    216204        """ 
    217         self.base.thaw_axes() 
    218         # Post paramters 
    219         event = SlicerParameterEvent() 
    220         event.type = self.__class__.__name__ 
    221         event.params = self.get_params() 
    222         wx.PostEvent(self.base.parent, event) 
    223         # create the new data1D 
    224205        self._post_data() 
    225206 
     
    240221        pass 
    241222 
    242     def get_params(self): 
     223    def getParams(self): 
    243224        """ 
    244225        Store a copy of values of parameters of the slicer into a dictionary. 
     
    248229        """ 
    249230        params = {} 
    250         params["x_max"] = math.fabs(self.vertical_lines.x) 
    251         params["y_max"] = math.fabs(self.horizontal_lines.y) 
     231        params["x_max"] = numpy.fabs(self.vertical_lines.x) 
     232        params["y_max"] = numpy.fabs(self.horizontal_lines.y) 
    252233        params["nbins"] = self.nbins 
    253234        return params 
    254235 
    255     def set_params(self, params): 
     236    def setParams(self, params): 
    256237        """ 
    257238        Receive a dictionary and reset the slicer with values contained 
     
    261242            values the user assigned to the slicer. 
    262243        """ 
    263         self.x = float(math.fabs(params["x_max"])) 
    264         self.y = float(math.fabs(params["y_max"])) 
     244        self.x = float(numpy.fabs(params["x_max"])) 
     245        self.y = float(numpy.fabs(params["y_max"])) 
    265246        self.nbins = params["nbins"] 
    266247 
     
    269250        self.post_data(nbins=None) 
    270251 
    271     def freeze_axes(self): 
    272         """ 
    273         """ 
    274         self.base.freeze_axes() 
    275  
    276     def thaw_axes(self): 
    277         """ 
    278         """ 
    279         self.base.thaw_axes() 
    280  
    281252    def draw(self): 
    282253        """ 
     
    294265        """ 
    295266        _BaseInteractor.__init__(self, base, axes, color=color) 
    296         # #Class initialization 
     267        # Class initialization 
    297268        self.markers = [] 
    298269        self.axes = axes 
    299         # # Saving the end points of two lines 
     270        # Saving the end points of two lines 
    300271        self.x = x 
    301272        self.save_x = x 
     
    303274        self.y = y 
    304275        self.save_y = y 
    305         # # Creating a marker 
     276        # Creating a marker 
    306277        # Inner circle marker 
    307278        self.inner_marker = self.axes.plot([0], [self.y], linestyle='', 
     
    311282                                           zorder=zorder, 
    312283                                           visible=True)[0] 
    313         # # Define 2 horizontal lines 
     284        # Define 2 horizontal lines 
    314285        self.top_line = self.axes.plot([self.x, -self.x], [self.y, self.y], 
    315286                                       linestyle='-', marker='', 
     
    318289                                          linestyle='-', marker='', 
    319290                                          color=self.color, visible=True)[0] 
    320         # # Flag to check the motion of the lines 
     291        # Flag to check the motion of the lines 
    321292        self.has_move = False 
    322         # # Connecting markers to mouse events and draw 
     293        # Connecting markers to mouse events and draw 
    323294        self.connect_markers([self.top_line, self.inner_marker]) 
    324295        self.update() 
     
    339310        """ 
    340311        self.clear_markers() 
    341         try: 
    342             self.inner_marker.remove() 
    343             self.top_line.remove() 
    344             self.bottom_line.remove() 
    345         except: 
    346             # Old version of matplotlib 
    347             for item in range(len(self.axes.lines)): 
    348                 del self.axes.lines[0] 
     312        self.inner_marker.remove() 
     313        self.top_line.remove() 
     314        self.bottom_line.remove() 
    349315 
    350316    def update(self, x=None, y=None): 
     
    356322 
    357323        """ 
    358         # # Reset x, y- coordinates if send as parameters 
     324        # Reset x, y- coordinates if send as parameters 
    359325        if x is not None: 
    360             self.x = np.sign(self.x) * math.fabs(x) 
     326            self.x = numpy.sign(self.x) * numpy.fabs(x) 
    361327        if y is not None: 
    362             self.y = np.sign(self.y) * math.fabs(y) 
    363         # # Draw lines and markers 
     328            self.y = numpy.sign(self.y) * numpy.fabs(y) 
     329        # Draw lines and markers 
    364330        self.inner_marker.set(xdata=[0], ydata=[self.y]) 
    365331        self.top_line.set(xdata=[self.x, -self.x], ydata=[self.y, self.y]) 
     
    373339        self.save_x = self.x 
    374340        self.save_y = self.y 
    375         self.base.freeze_axes() 
    376341 
    377342    def moveend(self, ev): 
     
    409374        self.markers = [] 
    410375        self.axes = axes 
    411         self.x = math.fabs(x) 
     376        self.x = numpy.fabs(x) 
    412377        self.save_x = self.x 
    413         self.y = math.fabs(y) 
     378        self.y = numpy.fabs(y) 
    414379        self.save_y = y 
    415380        # Inner circle marker 
     
    446411        """ 
    447412        self.clear_markers() 
    448         try: 
    449             self.inner_marker.remove() 
    450             self.left_line.remove() 
    451             self.right_line.remove() 
    452         except: 
    453             # Old version of matplotlib 
    454             for item in range(len(self.axes.lines)): 
    455                 del self.axes.lines[0] 
     413        self.inner_marker.remove() 
     414        self.left_line.remove() 
     415        self.right_line.remove() 
    456416 
    457417    def update(self, x=None, y=None): 
     
    463423 
    464424        """ 
    465         # # reset x, y -coordinates if given as parameters 
     425        # Reset x, y -coordinates if given as parameters 
    466426        if x is not None: 
    467             self.x = np.sign(self.x) * math.fabs(x) 
     427            self.x = numpy.sign(self.x) * numpy.fabs(x) 
    468428        if y is not None: 
    469             self.y = np.sign(self.y) * math.fabs(y) 
    470         # # draw lines and markers 
     429            self.y = numpy.sign(self.y) * numpy.fabs(y) 
     430        # Draw lines and markers 
    471431        self.inner_marker.set(xdata=[self.x], ydata=[0]) 
    472432        self.left_line.set(xdata=[-self.x, -self.x], ydata=[self.y, -self.y]) 
     
    480440        self.save_x = self.x 
    481441        self.save_y = self.y 
    482         self.base.freeze_axes() 
    483442 
    484443    def moveend(self, ev): 
     
    510469    Average in Qx direction 
    511470    """ 
    512     def __init__(self, base, axes, color='black', zorder=3): 
    513         BoxInteractor.__init__(self, base, axes, color=color) 
     471    def __init__(self, base, axes, item=None, color='black', zorder=3): 
     472        BoxInteractor.__init__(self, base, axes, item=item, color=color) 
    514473        self.base = base 
    515474        self._post_data() 
     
    527486    Average in Qy direction 
    528487    """ 
    529     def __init__(self, base, axes, color='black', zorder=3): 
    530         BoxInteractor.__init__(self, base, axes, color=color) 
     488    def __init__(self, base, axes, item=None, color='black', zorder=3): 
     489        BoxInteractor.__init__(self, base, axes, item=item, color=color) 
    531490        self.base = base 
    532491        self._post_data() 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/boxSum.py

    r7432acb rc416a17  
    11""" 
     2Boxsum Class: determine 2 rectangular area to compute 
     3the sum of pixel of a Data. 
     4""" 
     5import numpy 
     6from PyQt4 import QtGui 
     7from PyQt4 import QtCore 
     8from sas.qtgui.Utilities.GuiUtils import formatNumber 
     9 
     10from BaseInteractor import _BaseInteractor 
     11from sas.sascalc.dataloader.manipulations import Boxavg 
     12from sas.sascalc.dataloader.manipulations import Boxsum 
     13 
     14from sas.qtgui.Plotting.SlicerModel import SlicerModel 
     15 
     16 
     17class BoxSumCalculator(_BaseInteractor): 
     18    """ 
    219    Boxsum Class: determine 2 rectangular area to compute 
    320    the sum of pixel of a Data. 
    4 """ 
    5 import math 
    6 import wx 
    7 from BaseInteractor import _BaseInteractor 
    8 from sas.sasgui.guiframe.events import SlicerParamUpdateEvent 
    9 from sas.sasgui.guiframe.events import EVT_SLICER_PARS 
    10 from sas.sasgui.guiframe.events import StatusEvent 
    11  
    12  
    13 class BoxSum(_BaseInteractor): 
     21    Uses PointerInteractor , VerticalDoubleLine,HorizontalDoubleLine. 
     22    @param zorder:  Artists with lower zorder values are drawn first. 
     23    @param x_min: the minimum value of the x coordinate 
     24    @param x_max: the maximum value of the x coordinate 
     25    @param y_min: the minimum value of the y coordinate 
     26    @param y_max: the maximum value of the y coordinate 
     27 
    1428    """ 
    15         Boxsum Class: determine 2 rectangular area to compute 
    16         the sum of pixel of a Data. 
    17         Uses PointerInteractor , VerticalDoubleLine,HorizontalDoubleLine. 
    18         @param zorder:  Artists with lower zorder values are drawn first. 
    19         @param x_min: the minimum value of the x coordinate 
    20         @param x_max: the maximum value of the x coordinate 
    21         @param y_min: the minimum value of the y coordinate 
    22         @param y_max: the maximum value of the y coordinate 
    23  
    24     """ 
    25     def __init__(self, base, axes, color='black', zorder=3, x_min=0.008, 
    26                  x_max=0.008, y_min=0.0025, y_max=0.0025): 
    27         """ 
    28         """ 
     29    def __init__(self, base, axes, color='black', zorder=3): 
    2930        _BaseInteractor.__init__(self, base, axes, color=color) 
    30         # # class initialization 
    31         # # list of Boxsmun markers 
     31 
     32        # list of Boxsmun markers 
    3233        self.markers = [] 
    3334        self.axes = axes 
    34         # # connect the artist for the motion 
     35        self._model = None 
     36        self.update_model = False 
     37 
     38        # connect the artist for the motion 
    3539        self.connect = self.base.connect 
    36         # # when qmax is reached the selected line is reset the its previous value 
    37         self.qmax = min(self.base.data2D.xmax, self.base.data2D.xmin) 
    38         # # Define the boxsum limits 
    39         self.xmin = -1 * 0.5 * min(math.fabs(self.base.data2D.xmax), 
    40                                    math.fabs(self.base.data2D.xmin)) 
    41         self.ymin = -1 * 0.5 * min(math.fabs(self.base.data2D.xmax), 
    42                                    math.fabs(self.base.data2D.xmin)) 
    43         self.xmax = 0.5 * min(math.fabs(self.base.data2D.xmax), 
    44                               math.fabs(self.base.data2D.xmin)) 
    45         self.ymax = 0.5 * min(math.fabs(self.base.data2D.xmax), 
    46                               math.fabs(self.base.data2D.xmin)) 
    47         # # center of the boxSum 
     40 
     41        # when qmax is reached the selected line is reset the its previous value 
     42        self.qmax = min(self.base.data.xmax, self.base.data.xmin) 
     43 
     44        # Define the boxsum limits 
     45        self.xmin = -1 * 0.5 * min(numpy.fabs(self.base.data.xmax), 
     46                                   numpy.fabs(self.base.data.xmin)) 
     47        self.ymin = -1 * 0.5 * min(numpy.fabs(self.base.data.xmax), 
     48                                   numpy.fabs(self.base.data.xmin)) 
     49        self.xmax = 0.5 * min(numpy.fabs(self.base.data.xmax), 
     50                              numpy.fabs(self.base.data.xmin)) 
     51        self.ymax = 0.5 * min(numpy.fabs(self.base.data.xmax), 
     52                              numpy.fabs(self.base.data.xmin)) 
     53        # center of the boxSum 
    4854        self.center_x = 0.0002 
    4955        self.center_y = 0.0003 
    50         # # Number of points on the plot 
     56        # Number of points on the plot 
    5157        self.nbins = 20 
    52         # # Define initial result the summation 
     58        # Define initial result the summation 
    5359        self.count = 0 
    5460        self.error = 0 
     
    5662        self.totalerror = 0 
    5763        self.points = 0 
    58         # # Flag to determine if the current figure has moved 
    59         # # set to False == no motion , set to True== motion 
     64        # Flag to determine if the current figure has moved 
     65        # set to False == no motion , set to True== motion 
    6066        self.has_move = False 
    61         # # Create Boxsum edges 
     67        # Create Boxsum edges 
    6268        self.horizontal_lines = HorizontalDoubleLine(self, 
    63                                                      self.base.subplot, 
     69                                                     self.axes, 
    6470                                                     color='blue', 
    6571                                                     zorder=zorder, 
     
    7177 
    7278        self.vertical_lines = VerticalDoubleLine(self, 
    73                                                  self.base.subplot, 
     79                                                 self.axes, 
    7480                                                 color='black', 
    7581                                                 zorder=zorder, 
     
    8187 
    8288        self.center = PointInteractor(self, 
    83                                       self.base.subplot, color='grey', 
     89                                      self.axes, color='grey', 
    8490                                      zorder=zorder, 
    8591                                      center_x=self.center_x, 
    8692                                      center_y=self.center_y) 
    87         # # Save the name of the slicer panel associate with this slicer 
     93        # Save the name of the slicer panel associate with this slicer 
    8894        self.panel_name = "" 
    89         # # Update and post slicer parameters 
    90         self.update() 
    91         self._post_data() 
    92         # # Bind to slice parameter events 
    93         self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS) 
    94  
    95     def set_panel_name(self, name): 
    96         """ 
    97             Store the name of the panel associated to this slicer 
    98             @param name: the name of this panel 
     95        # Update and post slicer parameters 
     96        self.update_model = False 
     97        self.update() 
     98        self.postData() 
     99 
     100        # set up the model 
     101        self._model = QtGui.QStandardItemModel(1, 9) 
     102        self.setModelFromParams() 
     103        self.update_model = True 
     104        self._model.itemChanged.connect(self.setParamsFromModel) 
     105 
     106    def setModelFromParams(self): 
     107        """ 
     108        Set up the Qt model for data handling between controls 
     109        """ 
     110        parameters = self.getParams() 
     111        # Crete/overwrite model items 
     112        self._model.setData(self._model.index(0, 0), 
     113                    QtCore.QVariant(formatNumber(parameters['Height']))) 
     114        self._model.setData(self._model.index(0, 1), 
     115                    QtCore.QVariant(formatNumber(parameters['Width']))) 
     116        self._model.setData(self._model.index(0, 2), 
     117                    QtCore.QVariant(formatNumber(parameters['center_x']))) 
     118        self._model.setData(self._model.index(0, 3), 
     119                    QtCore.QVariant(formatNumber(parameters['center_y']))) 
     120 
     121        self.setReadOnlyParametersFromModel() 
     122 
     123    def model(self): 
     124        ''' model accessor ''' 
     125        return self._model 
     126 
     127    def setReadOnlyParametersFromModel(self): 
     128        """ 
     129        Cast model content onto "read-only" subset of parameters 
     130        """ 
     131        parameters = self.getParams() 
     132        self._model.setData(self._model.index(0, 4), 
     133                    QtCore.QVariant(formatNumber(parameters['avg']))) 
     134        self._model.setData(self._model.index(0, 5), 
     135                    QtCore.QVariant(formatNumber(parameters['avg_error']))) 
     136        self._model.setData(self._model.index(0, 6), 
     137                    QtCore.QVariant(formatNumber(parameters['sum']))) 
     138        self._model.setData(self._model.index(0, 7), 
     139                    QtCore.QVariant(formatNumber(parameters['sum_error']))) 
     140        self._model.setData(self._model.index(0, 8), 
     141                    QtCore.QVariant(formatNumber(parameters['num_points']))) 
     142 
     143    def setParamsFromModel(self): 
     144        """ 
     145        Cast model content onto params dict 
     146        """ 
     147        params = {} 
     148        params["Height"] = float(self.model().item(0, 0).text()) 
     149        params["Width"] = float(self.model().item(0, 1).text()) 
     150        params["center_x"] = float(self.model().item(0, 2).text()) 
     151        params["center_y"] = float(self.model().item(0, 3).text()) 
     152        self.update_model = False 
     153        self.setParams(params) 
     154        self.setReadOnlyParametersFromModel() 
     155        self.update_model = True 
     156 
     157    def setPanelName(self, name): 
     158        """ 
     159        Store the name of the panel associated to this slicer 
     160        @param name: the name of this panel 
    99161        """ 
    100162        self.panel_name = name 
    101163 
    102     def _onEVT_SLICER_PARS(self, event): 
    103         """ 
    104             receive an event containing parameters values to reset the slicer 
    105             @param event: event of type SlicerParameterEvent with params as 
    106             attribute 
    107         """ 
    108         # # Post e message to declare what kind of event has being received 
    109         wx.PostEvent(self.base.parent, 
    110                      StatusEvent(status="Boxsum._onEVT_SLICER_PARS")) 
    111         event.Skip() 
    112         # # reset the slicer with the values contains the event.params dictionary 
    113         if event.type == self.__class__.__name__: 
    114             self.set_params(event.params) 
    115             self.base.update() 
    116  
    117     def set_layer(self, n): 
     164    def setLayer(self, n): 
    118165        """ 
    119166        Allow adding plot to the same panel 
     
    132179        self.center.clear() 
    133180        self.base.connect.clearall() 
    134         self.base.Unbind(EVT_SLICER_PARS) 
    135181 
    136182    def update(self): 
     
    139185        resetting the widgets. 
    140186        """ 
    141         # # check if the center point has moved and update the figure accordingly 
     187        # check if the center point has moved and update the figure accordingly 
    142188        if self.center.has_move: 
    143189            self.center.update() 
    144190            self.horizontal_lines.update(center=self.center) 
    145191            self.vertical_lines.update(center=self.center) 
    146         # # check if the horizontal lines have moved and 
     192        # check if the horizontal lines have moved and 
    147193        # update the figure accordingly 
    148194        if self.horizontal_lines.has_move: 
     
    151197                                       y2=self.horizontal_lines.y2, 
    152198                                       height=self.horizontal_lines.half_height) 
    153         # # check if the vertical lines have moved and 
     199        # check if the vertical lines have moved and 
    154200        # update the figure accordingly 
    155201        if self.vertical_lines.has_move: 
     
    164210        can restore on Esc. 
    165211        """ 
    166         self.base.freeze_axes() 
    167212        self.horizontal_lines.save(ev) 
    168213        self.vertical_lines.save(ev) 
    169214        self.center.save(ev) 
    170215 
    171     def _post_data(self): 
     216    def postData(self): 
    172217        """ 
    173218        Get the limits of the boxsum and compute the sum of the pixel 
    174219        contained in that region and the error on that sum 
    175220        """ 
    176         # # the region of the summation 
     221        # the region of the summation 
    177222        x_min = self.horizontal_lines.x2 
    178223        x_max = self.horizontal_lines.x1 
    179224        y_min = self.vertical_lines.y2 
    180225        y_max = self.vertical_lines.y1 
    181         # #computation of the sum and its error 
    182         from sas.sascalc.dataloader.manipulations import Boxavg 
     226        #computation of the sum and its error 
    183227        box = Boxavg(x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max) 
    184         self.count, self.error = box(self.base.data2D) 
     228        self.count, self.error = box(self.base.data) 
    185229        # Dig out number of points summed, SMK & PDB, 04/03/2013 
    186         from sas.sascalc.dataloader.manipulations import Boxsum 
    187230        boxtotal = Boxsum(x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max) 
    188         self.total, self.totalerror, self.points = boxtotal(self.base.data2D) 
     231        self.total, self.totalerror, self.points = boxtotal(self.base.data) 
     232        if self.update_model: 
     233            self.setModelFromParams() 
     234        self.draw() 
    189235 
    190236    def moveend(self, ev): 
    191237        """ 
    192             After a dragging motion this function is called to compute 
    193             the error and the sum of pixel of a given data 2D 
    194         """ 
    195         self.base.thaw_axes() 
    196         # # compute error an d sum of data's pixel 
    197         self._post_data() 
    198         # # Create and event ( posted to guiframe)that  set the 
    199         # #current slicer parameter to a panel of name self.panel_name 
    200         self.type = self.__class__.__name__ 
    201         params = self.get_params() 
    202         event = SlicerParamUpdateEvent(type=self.type, 
    203                                        params=params, 
    204                                        panel_name=self.panel_name) 
    205         wx.PostEvent(self.base.parent, event) 
     238        After a dragging motion this function is called to compute 
     239        the error and the sum of pixel of a given data 2D 
     240        """ 
     241        # compute error an d sum of data's pixel 
     242        self.postData() 
    206243 
    207244    def restore(self): 
     
    213250        self.center.restore() 
    214251 
    215     def move(self, x, y, ev): 
    216         """ 
    217         Process move to a new position, making sure that the move is allowed. 
    218         """ 
    219         pass 
    220  
    221     def set_cursor(self, x, y): 
    222         """ 
    223         """ 
    224         pass 
    225  
    226     def get_params(self): 
     252    def getParams(self): 
    227253        """ 
    228254        Store a copy of values of parameters of the slicer into a dictionary. 
     
    230256        """ 
    231257        params = {} 
    232         params["Width"] = math.fabs(self.vertical_lines.half_width) * 2 
    233         params["Height"] = math.fabs(self.horizontal_lines.half_height) * 2 
     258        params["Width"] = numpy.fabs(self.vertical_lines.half_width) * 2 
     259        params["Height"] = numpy.fabs(self.horizontal_lines.half_height) * 2 
    234260        params["center_x"] = self.center.x 
    235261        params["center_y"] = self.center.y 
     
    241267        return params 
    242268 
    243     def get_result(self): 
    244         """ 
    245             return the result of box summation 
     269    def getResult(self): 
     270        """ 
     271        Return the result of box summation 
    246272        """ 
    247273        result = {} 
     
    253279        return result 
    254280 
    255     def set_params(self, params): 
     281    def setParams(self, params): 
    256282        """ 
    257283        Receive a dictionary and reset the slicer with values contained 
    258284        in the values of the dictionary. 
    259         :param params: a dictionary containing name of slicer parameters and values the user assigned to the slicer. 
    260         """ 
    261         x_max = math.fabs(params["Width"]) / 2 
    262         y_max = math.fabs(params["Height"]) / 2 
     285        :param params: a dictionary containing name of slicer parameters 
     286        and values the user assigned to the slicer. 
     287        """ 
     288        x_max = numpy.fabs(params["Width"]) / 2 
     289        y_max = numpy.fabs(params["Height"]) / 2 
    263290 
    264291        self.center_x = params["center_x"] 
     
    271298                                   width=x_max, height=y_max) 
    272299        # compute the new error and sum given values of params 
    273         self._post_data() 
    274  
    275     def freeze_axes(self): 
    276         """ 
    277         """ 
    278         self.base.freeze_axes() 
    279  
    280     def thaw_axes(self): 
    281         """ 
    282         """ 
    283         self.base.thaw_axes() 
     300        self.postData() 
    284301 
    285302    def draw(self): 
    286         """ 
    287         """ 
     303        """ Redraw canvas""" 
    288304        self.base.draw() 
    289305 
     
    297313    def __init__(self, base, axes, color='black', zorder=5, center_x=0.0, 
    298314                 center_y=0.0): 
    299         """ 
    300         """ 
    301315        _BaseInteractor.__init__(self, base, axes, color=color) 
    302         # # Initialization the class 
     316        # Initialization the class 
    303317        self.markers = [] 
    304318        self.axes = axes 
     
    306320        self.x = center_x 
    307321        self.y = center_y 
    308         # # saved value of the center coordinates 
     322        # saved value of the center coordinates 
    309323        self.save_x = center_x 
    310324        self.save_y = center_y 
    311         # # Create a marker 
     325        # Create a marker 
    312326        self.center_marker = self.axes.plot([self.x], [self.y], linestyle='', 
    313327                                            marker='s', markersize=10, 
     
    316330                                            zorder=zorder, 
    317331                                            visible=True)[0] 
    318         # # Draw a point 
     332        # Draw a point 
    319333        self.center = self.axes.plot([self.x], [self.y], 
    320334                                     linestyle='-', marker='', 
    321335                                     color=self.color, 
    322336                                     visible=True)[0] 
    323         # # Flag to determine the motion this point 
     337        # Flag to determine the motion this point 
    324338        self.has_move = False 
    325         # # connecting the marker to allow them to move 
     339        # connecting the marker to allow them to move 
    326340        self.connect_markers([self.center_marker]) 
    327         # # Update the figure 
    328         self.update() 
    329  
    330     def set_layer(self, n): 
    331         """ 
    332             Allow adding plot to the same panel 
    333             @param n: the number of layer 
     341        # Update the figure 
     342        self.update() 
     343 
     344    def setLayer(self, n): 
     345        """ 
     346        Allow adding plot to the same panel 
     347        @param n: the number of layer 
    334348        """ 
    335349        self.layernum = n 
     
    338352    def clear(self): 
    339353        """ 
    340             Clear this figure and its markers 
     354        Clear this figure and its markers 
    341355        """ 
    342356        self.clear_markers() 
    343         try: 
    344             self.center.remove() 
    345             self.center_marker.remove() 
    346         except: 
    347             # Old version of matplotlib 
    348             for item in range(len(self.axes.lines)): 
    349                 del self.axes.lines[0] 
     357        self.center.remove() 
     358        self.center_marker.remove() 
    350359 
    351360    def update(self, center_x=None, center_y=None): 
    352361        """ 
    353             Draw the new roughness on the graph. 
     362        Draw the new roughness on the graph. 
    354363        """ 
    355364        if center_x is not None: 
     
    367376        self.save_x = self.x 
    368377        self.save_y = self.y 
    369         self.base.freeze_axes() 
    370378 
    371379    def moveend(self, ev): 
     
    391399        self.base.base.update() 
    392400 
    393     def set_cursor(self, x, y): 
     401    def setCursor(self, x, y): 
    394402        """ 
    395403        """ 
     
    399407class VerticalDoubleLine(_BaseInteractor): 
    400408    """ 
    401          Draw 2 vertical lines moving in opposite direction and centered on 
    402          a point (PointInteractor) 
     409    Draw 2 vertical lines moving in opposite direction and centered on 
     410    a point (PointInteractor) 
    403411    """ 
    404412    def __init__(self, base, axes, color='black', zorder=5, x=0.5, y=0.5, 
    405413                 center_x=0.0, center_y=0.0): 
    406         """ 
    407         """ 
    408414        _BaseInteractor.__init__(self, base, axes, color=color) 
    409         # # Initialization the class 
     415        # Initialization the class 
    410416        self.markers = [] 
    411417        self.axes = axes 
    412         # # Center coordinates 
     418        # Center coordinates 
    413419        self.center_x = center_x 
    414420        self.center_y = center_y 
    415         # # defined end points vertical lignes and their saved values 
     421        # defined end points vertical lignes and their saved values 
    416422        self.y1 = y + self.center_y 
    417423        self.save_y1 = self.y1 
     
    429435        # # save the color of the line 
    430436        self.color = color 
    431         # # the height of the rectangle 
    432         self.half_height = math.fabs(y) 
    433         self.save_half_height = math.fabs(y) 
    434         # # the with of the rectangle 
    435         self.half_width = math.fabs(self.x1 - self.x2) / 2 
    436         self.save_half_width = math.fabs(self.x1 - self.x2) / 2 
    437         # # Create marker 
     437        # the height of the rectangle 
     438        self.half_height = numpy.fabs(y) 
     439        self.save_half_height = numpy.fabs(y) 
     440        # the with of the rectangle 
     441        self.half_width = numpy.fabs(self.x1 - self.x2) / 2 
     442        self.save_half_width = numpy.fabs(self.x1 - self.x2) / 2 
     443        # Create marker 
    438444        self.right_marker = self.axes.plot([self.x1], [0], linestyle='', 
    439445                                           marker='s', markersize=10, 
     
    442448                                           zorder=zorder, visible=True)[0] 
    443449 
    444         # # define the left and right lines of the rectangle 
     450        # Define the left and right lines of the rectangle 
    445451        self.right_line = self.axes.plot([self.x1, self.x1], [self.y1, self.y2], 
    446452                                         linestyle='-', marker='', 
     
    449455                                        linestyle='-', marker='', 
    450456                                        color=self.color, visible=True)[0] 
    451         # # Flag to determine if the lines have moved 
     457        # Flag to determine if the lines have moved 
    452458        self.has_move = False 
    453         # # connection the marker and draw the pictures 
     459        # Connection the marker and draw the pictures 
    454460        self.connect_markers([self.right_marker]) 
    455461        self.update() 
    456462 
    457     def set_layer(self, n): 
     463    def setLayer(self, n): 
    458464        """ 
    459465        Allow adding plot to the same panel 
     
    468474        """ 
    469475        self.clear_markers() 
    470         try: 
    471             self.right_marker.remove() 
    472             self.right_line.remove() 
    473             self.left_line.remove() 
    474         except: 
    475             # Old version of matplotlib 
    476             for item in range(len(self.axes.lines)): 
    477                 del self.axes.lines[0] 
     476        self.right_marker.remove() 
     477        self.right_line.remove() 
     478        self.left_line.remove() 
    478479 
    479480    def update(self, x1=None, x2=None, y1=None, y2=None, width=None, 
     
    489490        :param center: provided x, y  coordinates of the center point 
    490491        """ 
    491         # # save the new height, witdh of the rectangle if given as a param 
     492        # Save the new height, witdh of the rectangle if given as a param 
    492493        if width is not None: 
    493494            self.half_width = width 
    494495        if height is not None: 
    495496            self.half_height = height 
    496         # # If new  center coordinates are given draw the rectangle 
    497         # #given these value 
     497        # If new  center coordinates are given draw the rectangle 
     498        # given these value 
    498499        if center is not None: 
    499500            self.center_x = center.x 
     
    510511                               ydata=[self.y1, self.y2]) 
    511512            return 
    512         # # if x1, y1, y2, y3 are given draw the rectangle with this value 
     513        # if x1, y1, y2, y3 are given draw the rectangle with this value 
    513514        if x1 is not None: 
    514515            self.x1 = x1 
     
    519520        if y2 is not None: 
    520521            self.y2 = y2 
    521         # # Draw 2 vertical lines and a marker 
     522        # Draw 2 vertical lines and a marker 
    522523        self.right_marker.set(xdata=[self.x1], ydata=[self.center_y]) 
    523524        self.right_line.set(xdata=[self.x1, self.x1], ydata=[self.y1, self.y2]) 
     
    535536        self.save_half_height = self.half_height 
    536537        self.save_half_width = self.half_width 
    537         self.base.freeze_axes() 
    538538 
    539539    def moveend(self, ev): 
    540540        """ 
    541             After a dragging motion reset the flag self.has_move to False 
     541        After a dragging motion reset the flag self.has_move to False 
    542542        """ 
    543543        self.has_move = False 
     
    562562        delta = self.x1 - self.center_x 
    563563        self.x2 = self.center_x - delta 
    564         self.half_width = math.fabs(self.x1 - self.x2) / 2 
     564        self.half_width = numpy.fabs(self.x1 - self.x2) / 2 
    565565        self.has_move = True 
    566566        self.base.base.update() 
    567567 
    568     def set_cursor(self, x, y): 
    569         """ 
    570             Update the figure given x and y 
     568    def setCursor(self, x, y): 
     569        """ 
     570        Update the figure given x and y 
    571571        """ 
    572572        self.move(x, y, None) 
     
    575575class HorizontalDoubleLine(_BaseInteractor): 
    576576    """ 
    577          Select an annulus through a 2D plot 
     577    Select an annulus through a 2D plot 
    578578    """ 
    579579    def __init__(self, base, axes, color='black', zorder=5, x=0.5, y=0.5, 
     
    581581 
    582582        _BaseInteractor.__init__(self, base, axes, color=color) 
    583         # # Initialization the class 
     583        # Initialization the class 
    584584        self.markers = [] 
    585585        self.axes = axes 
    586         # # Center coordinates 
     586        # Center coordinates 
    587587        self.center_x = center_x 
    588588        self.center_y = center_y 
     
    598598        self.save_x2 = self.x2 
    599599        self.color = color 
    600         self.half_height = math.fabs(y) 
    601         self.save_half_height = math.fabs(y) 
    602         self.half_width = math.fabs(x) 
    603         self.save_half_width = math.fabs(x) 
     600        self.half_height = numpy.fabs(y) 
     601        self.save_half_height = numpy.fabs(y) 
     602        self.half_width = numpy.fabs(x) 
     603        self.save_half_width = numpy.fabs(x) 
    604604        self.top_marker = self.axes.plot([0], [self.y1], linestyle='', 
    605605                                         marker='s', markersize=10, 
     
    616616                                          linestyle='-', marker='', 
    617617                                          color=self.color, visible=True)[0] 
    618         # # Flag to determine if the lines have moved 
     618        # Flag to determine if the lines have moved 
    619619        self.has_move = False 
    620         # # connection the marker and draw the pictures 
     620        # connection the marker and draw the pictures 
    621621        self.connect_markers([self.top_marker]) 
    622622        self.update() 
    623623 
    624     def set_layer(self, n): 
    625         """ 
    626             Allow adding plot to the same panel 
    627             @param n: the number of layer 
     624    def setLayer(self, n): 
     625        """ 
     626        Allow adding plot to the same panel 
     627        @param n: the number of layer 
    628628        """ 
    629629        self.layernum = n 
     
    632632    def clear(self): 
    633633        """ 
    634             Clear this figure and its markers 
     634        Clear this figure and its markers 
    635635        """ 
    636636        self.clear_markers() 
    637         try: 
    638             self.top_marker.remove() 
    639             self.bottom_line.remove() 
    640             self.top_line.remove() 
    641         except: 
    642             # Old version of matplotlib 
    643             for item in range(len(self.axes.lines)): 
    644                 del self.axes.lines[0] 
     637        self.top_marker.remove() 
     638        self.bottom_line.remove() 
     639        self.top_line.remove() 
    645640 
    646641    def update(self, x1=None, x2=None, y1=None, y2=None, 
     
    656651        :param center: provided x, y  coordinates of the center point 
    657652        """ 
    658         # # save the new height, witdh of the rectangle if given as a param 
     653        # Save the new height, witdh of the rectangle if given as a param 
    659654        if width is not None: 
    660655            self.half_width = width 
    661656        if height is not None: 
    662657            self.half_height = height 
    663         # # If new  center coordinates are given draw the rectangle 
    664         # #given these value 
     658        # If new  center coordinates are given draw the rectangle 
     659        # given these value 
    665660        if center is not None: 
    666661            self.center_x = center.x 
     
    678673                                 ydata=[self.y2, self.y2]) 
    679674            return 
    680         # # if x1, y1, y2, y3 are given draw the rectangle with this value 
     675        # if x1, y1, y2, y3 are given draw the rectangle with this value 
    681676        if x1 is not None: 
    682677            self.x1 = x1 
     
    687682        if y2 is not None: 
    688683            self.y2 = y2 
    689         # # Draw 2 vertical lines and a marker 
     684        # Draw 2 vertical lines and a marker 
    690685        self.top_marker.set(xdata=[self.center_x], ydata=[self.y1]) 
    691686        self.top_line.set(xdata=[self.x1, self.x2], ydata=[self.y1, self.y1]) 
     
    703698        self.save_half_height = self.half_height 
    704699        self.save_half_width = self.half_width 
    705         self.base.freeze_axes() 
    706700 
    707701    def moveend(self, ev): 
     
    730724        delta = self.y1 - self.center_y 
    731725        self.y2 = self.center_y - delta 
    732         self.half_height = math.fabs(self.y1) - self.center_y 
     726        self.half_height = numpy.fabs(self.y1) - self.center_y 
    733727        self.has_move = True 
    734728        self.base.base.update() 
    735729 
    736     def set_cursor(self, x, y): 
    737         """ 
    738             Update the figure given x and y 
     730    def setCursor(self, x, y): 
     731        """ 
     732        Update the figure given x and y 
    739733        """ 
    740734        self.move(x, y, None) 
Note: See TracChangeset for help on using the changeset viewer.