Ignore:
Timestamp:
Apr 10, 2017 4:01:46 AM (8 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:
6c8fb2c
Parents:
9208346 (diff), c6f3aec (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/plotting
Files:
8 edited

Legend:

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

    r5bcb6a9 r9687d58  
    6565        # context menu 
    6666        self._slicerpop = None 
    67  
    6867        self._available_data = [] 
    6968        self._symbol_labels = self.get_symbol_label() 
     
    9594        self.parent.SetFocus() 
    9695 
     96        # If true, there are 3 qrange bars 
     97        self.is_corfunc = False 
     98 
    9799 
    98100    def get_symbol_label(self): 
     
    214216        if active_ctrl == None: 
    215217            return 
     218        if hasattr(event, 'is_corfunc'): 
     219            self.is_corfunc = event.is_corfunc 
    216220        if event.id in self.plots.keys(): 
    217221            ctrl = event.ctrl 
     
    222226            values = [max(x_data.min(), float(ctrl[0].GetValue())), 
    223227                      min(x_data.max(), float(ctrl[1].GetValue()))] 
     228            if len(ctrl) == 3: 
     229                colors.append('purple') 
     230                values.append(min(x_data.max(), float(ctrl[2].GetValue()))) 
    224231            if self.ly == None: 
    225232                self.ly = [] 
     
    232239                xval = float(active_ctrl.GetValue()) 
    233240                position = self.get_data_xy_vals(xval) 
    234                 if position != None: 
     241                if position != None and not self.is_corfunc: 
    235242                    wx.PostEvent(self.parent, StatusEvent(status=position)) 
    236243            except: 
     
    293300        ly0x = ly[0].get_xdata() 
    294301        ly1x = ly[1].get_xdata() 
     302        ly2x = None 
     303        if self.is_corfunc: ly2x = ly[2].get_xdata() 
    295304        self.q_ctrl[0].SetBackgroundColour('white') 
    296305        self.q_ctrl[1].SetBackgroundColour('white') 
     
    306315                self.q_ctrl[0].SetValue(str(pos_x)) 
    307316                self.q_ctrl[1].SetBackgroundColour('pink') 
     317        elif ly2x is not None and ly1x >= ly2x: 
     318            if self.vl_ind == 1: 
     319                ly[2].set_xdata(posx) 
     320                ly[2].set_zorder(nop) 
     321                self.q_ctrl[2].SetValue(str(pos_x)) 
     322            elif self.vl_ind == 2: 
     323                ly[1].set_xdata(posx) 
     324                ly[1].set_zorder(nop) 
     325                self.q_ctrl[1].SetValue(str(pos_x)) 
     326 
    308327 
    309328    def _get_cusor_lines(self, event): 
     
    325344            dqmin = math.fabs(event.xdata - self.ly[0].get_xdata()) 
    326345            dqmax = math.fabs(event.xdata - self.ly[1].get_xdata()) 
    327             is_qmax = dqmin > dqmax 
    328             if is_qmax: 
    329                 self.vl_ind = 1 
     346            if not self.is_corfunc: 
     347                is_qmax = dqmin > dqmax 
     348                if is_qmax: 
     349                    self.vl_ind = 1 
     350                else: 
     351                    self.vl_ind = 0 
    330352            else: 
    331                 self.vl_ind = 0 
     353                dqmax2 = math.fabs(event.xdata - self.ly[2].get_xdata()) 
     354                closest = min(dqmin, dqmax, dqmax2) 
     355                self.vl_ind = { dqmin: 0, dqmax: 1, dqmax2: 2 }.get(closest) 
    332356 
    333357    def cusor_line(self, event): 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter2D.py

    r2d647cf rb2b36932  
    316316 
    317317        slicerpop.AppendSeparator() 
    318         if len(self.data2D.detector) == 1: 
     318        if len(self.data2D.detector) <= 1: 
    319319            item_list = self.parent.get_current_context_menu(self) 
    320320            if (not item_list == None) and (not len(item_list) == 0) and\ 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/plotting.py

    rd85c194 r6ffa0dd  
    1616from sas.sasgui.guiframe.events import EVT_NEW_PLOT 
    1717from sas.sasgui.guiframe.events import EVT_PLOT_QRANGE 
     18from sas.sasgui.guiframe.events import EVT_PLOT_LIM 
    1819from sas.sasgui.guiframe.events import DeletePlotPanelEvent 
    1920from sas.sasgui.guiframe.plugin_base import PluginBase 
     
    7980        self.parent.Bind(EVT_NEW_PLOT, self._on_plot_event) 
    8081        self.parent.Bind(EVT_PLOT_QRANGE, self._on_plot_qrange) 
     82        self.parent.Bind(EVT_PLOT_LIM, self._on_plot_lim) 
    8183        # We have no initial panels for this plug-in 
    8284        return [] 
     
    9597            return 
    9698        panel.on_plot_qrange(event) 
     99 
     100    def _on_plot_lim(self, event=None): 
     101        if event == None: 
     102            return 
     103        if event.id in self.plot_panels.keys(): 
     104            panel = self.plot_panels[event.id] 
     105        elif event.group_id in self.plot_panels.keys(): 
     106            panel = self.plot_panels[event.group_id] 
     107        else: 
     108            return 
     109        if hasattr(event, 'xlim'): 
     110            panel.subplot.set_xlim(event.xlim) 
     111        if hasattr(event, 'ylim'): 
     112            panel.subplot.set_ylim(event.ylim) 
     113 
    97114 
    98115    def _on_show_panel(self, event): 
     
    312329                new_panel = self.create_2d_panel(data, group_id) 
    313330            self.create_panel_helper(new_panel, data, group_id, title) 
     331            if hasattr(event, 'xlim'): 
     332                new_panel.subplot.set_xlim(event.xlim) 
     333            if hasattr(event, 'ylim'): 
     334                new_panel.subplot.set_ylim(event.ylim) 
    314335        return 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/AnnulusSlicer.py

    rd85c194 r116260a  
    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.GuiUtils as GuiUtils 
     8from sas.qtgui.GuiUtils import formatNumber 
     9from sas.qtgui.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 
    124         if data == None: 
     99        data = self.base.data 
     100        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 
    134         if nbins == None: 
     110        if nbins is None: 
    135111            self.nbins = 36 
    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 != 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 
     
    521467 
    522468        # If we have no data, just return 
    523         if data == None: 
     469        if data is None: 
    524470            return 
    525471        mask = data.mask 
     
    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/SectorSlicer.py

    rd85c194 r116260a  
    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.GuiUtils as GuiUtils 
     11from sas.qtgui.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         ## Middle line 
    40         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', 
    4144                                        zorder=zorder, r=self.qmax, 
    4245                                        theta=self.theta2) 
    4346        self.main_line.qmax = self.qmax 
    44         ## Right Side line 
    45         self.right_line = SideInteractor(self, self.base.subplot, color='black', 
     47        # Right Side line 
     48        self.right_line = SideInteractor(self, self.axes, color='black', 
    4649                                         zorder=zorder, r=self.qmax, 
    4750                                         phi=-1 * self.phi, theta2=self.theta2) 
    4851        self.right_line.qmax = self.qmax 
    49         ## Left Side line 
    50         self.left_line = SideInteractor(self, self.base.subplot, color='black', 
     52        # Left Side line 
     53        self.left_line = SideInteractor(self, self.axes, color='black', 
    5154                                        zorder=zorder, r=self.qmax, 
    5255                                        phi=self.phi, theta2=self.theta2) 
    5356        self.left_line.qmax = self.qmax 
    54         ## draw the sector 
     57        # draw the sector 
    5558        self.update() 
    5659        self._post_data() 
    57         ## Bind to slice parameter events 
    58         self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS) 
    59  
    60     def _onEVT_SLICER_PARS(self, event): 
    61         """ 
    62         receive an event containing parameters values to reset the slicer 
    63  
    64         :param event: event of type SlicerParameterEvent with params as 
    65         attribute 
    66  
    67         """ 
    68         wx.PostEvent(self.base.parent, 
    69                      StatusEvent(status="SectorSlicer._onEVT_SLICER_PARS")) 
    70         event.Skip() 
    71         if event.type == self.__class__.__name__: 
    72             self.set_params(event.params) 
    73             self.base.update() 
     60        self.setModelFromParams() 
    7461 
    7562    def set_layer(self, n): 
    7663        """ 
    7764         Allow adding plot to the same panel 
    78  
    7965        :param n: the number of layer 
    80  
    8166        """ 
    8267        self.layernum = n 
     
    9277        self.right_line.clear() 
    9378        self.base.connect.clearall() 
    94         self.base.Unbind(EVT_SLICER_PARS) 
    9579 
    9680    def update(self): 
     
    10084        """ 
    10185        # Update locations 
    102         ## Check if the middle line was dragged and 
    103         #update the picture accordingly 
     86        # Check if the middle line was dragged and 
     87        # update the picture accordingly 
    10488        if self.main_line.has_move: 
    10589            self.main_line.update() 
     
    10892            self.left_line.update(delta=self.left_line.phi / 2, 
    10993                                  mline=self.main_line.theta) 
    110         ## 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 
    11195        if self.left_line.has_move: 
    11296            self.main_line.update() 
     
    116100                                   mline=self.main_line, side=True, 
    117101                                   left=False, right=True) 
    118         ## Check if the right side line has moved and 
    119         #update the slicer accordingly 
     102        # Check if the right side line has moved and update the slicer accordingly 
    120103        if self.right_line.has_move: 
    121104            self.main_line.update() 
     
    130113        can restore on Esc. 
    131114        """ 
    132         self.base.freeze_axes() 
    133115        self.main_line.save(ev) 
    134116        self.right_line.save(ev) 
     
    141123        :param nbins: the number of point to plot for the average 1D data 
    142124        """ 
    143         ## get the data2D to average 
    144         data = self.base.data2D 
     125        # Get the data2D to average 
     126        data = self.base.data 
    145127        # If we have no data, just return 
    146128        if data == None: 
    147129            return 
    148         ## Averaging 
     130        # Averaging 
    149131        from sas.sascalc.dataloader.manipulations import SectorQ 
    150132        radius = self.qmax 
     
    154136            nbins = 20 
    155137        sect = SectorQ(r_min=0.0, r_max=radius, 
    156                        phi_min=phimin + math.pi, 
    157                        phi_max=phimax + math.pi, nbins=nbins) 
    158  
    159         sector = sect(self.base.data2D) 
    160         ##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 
    161143 
    162144        if hasattr(sector, "dxl"): 
     
    171153        new_plot.dxl = dxl 
    172154        new_plot.dxw = dxw 
    173         new_plot.name = "SectorQ" + "(" + self.base.data2D.name + ")" 
    174         new_plot.source = self.base.data2D.source 
    175         #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 
    176158        new_plot.interactive = True 
    177         new_plot.detector = self.base.data2D.detector 
    178         ## 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. 
    179161        new_plot.xaxis("\\rm{Q}", "A^{-1}") 
    180162        new_plot.yaxis("\\rm{Intensity}", "cm^{-1}") 
    181163        if hasattr(data, "scale") and data.scale == 'linear' and \ 
    182                 self.base.data2D.name.count("Residuals") > 0: 
     164                self.base.data.name.count("Residuals") > 0: 
    183165            new_plot.ytransform = 'y' 
    184166            new_plot.yaxis("\\rm{Residuals} ", "/") 
    185167 
    186         new_plot.group_id = "2daverage" + self.base.data2D.name 
    187         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 
    188170        new_plot.is_data = True 
    189         self.base.parent.update_theory(data_id=data.id, theory=new_plot) 
    190         wx.PostEvent(self.base.parent, 
    191                      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 
    192197 
    193198    def moveend(self, ev): 
     
    195200        Called a dragging motion ends.Get slicer event 
    196201        """ 
    197         self.base.thaw_axes() 
    198         ## Post parameters 
    199         event = SlicerParameterEvent() 
    200         event.type = self.__class__.__name__ 
    201         event.params = self.get_params() 
    202         ## Send slicer paramers to plotter2D 
    203         wx.PostEvent(self.base, event) 
     202        # Post parameters 
     203        self._post_data(self.nbins) 
    204204 
    205205    def restore(self): 
     
    222222        pass 
    223223 
    224     def get_params(self): 
     224    def getParams(self): 
    225225        """ 
    226226        Store a copy of values of parameters of the slicer into a dictionary. 
    227  
    228227        :return params: the dictionary created 
    229  
    230228        """ 
    231229        params = {} 
    232         ## Always make sure that the left and the right line are at phi 
    233         ## angle of the middle line 
    234         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): 
    235233            msg = "Phi left and phi right are different" 
    236234            msg += " %f, %f" % (self.left_line.phi, self.right_line.phi) 
    237235            raise ValueError, msg 
    238         params["Phi [deg]"] = self.main_line.theta * 180 / math.pi 
    239         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) 
    240238        params["nbins"] = self.nbins 
    241239        return params 
    242240 
    243     def set_params(self, params): 
     241    def setParams(self, params): 
    244242        """ 
    245243        Receive a dictionary and reset the slicer with values contained 
     
    249247            values the user assigned to the slicer. 
    250248        """ 
    251         main = params["Phi [deg]"] * math.pi / 180 
    252         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 
    253257        self.nbins = int(params["nbins"]) 
    254258        self.main_line.theta = main 
    255         ## Reset the slicer parameters 
     259        # Reset the slicer parameters 
    256260        self.main_line.update() 
    257261        self.right_line.update(phi=phi, delta=None, mline=self.main_line, 
     
    259263        self.left_line.update(phi=phi, delta=None, 
    260264                              mline=self.main_line, side=True) 
    261         ## post the new corresponding data 
     265        # Post the new corresponding data 
    262266        self._post_data(nbins=self.nbins) 
    263267 
    264     def freeze_axes(self): 
    265         """ 
    266         """ 
    267         self.base.freeze_axes() 
    268  
    269     def thaw_axes(self): 
    270         """ 
    271         """ 
    272         self.base.thaw_axes() 
    273  
    274268    def draw(self): 
    275269        """ 
     270        Redraw canvas 
    276271        """ 
    277272        self.base.draw() 
     
    287282    """ 
    288283    def __init__(self, base, axes, color='black', zorder=5, r=1.0, 
    289                  phi=math.pi / 4, theta2=math.pi / 3): 
     284                 phi=numpy.pi / 4, theta2=numpy.pi / 3): 
    290285        """ 
    291286        """ 
    292287        _BaseInteractor.__init__(self, base, axes, color=color) 
    293         ## Initialize the class 
     288        # Initialize the class 
    294289        self.markers = [] 
    295290        self.axes = axes 
    296         ## compute the value of the angle between the current line and 
    297         ## the x-axis 
     291        # compute the value of the angle between the current line and 
     292        # the x-axis 
    298293        self.save_theta = theta2 + phi 
    299294        self.theta = theta2 + phi 
    300         ## 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 
    301296        self.theta2 = theta2 
    302         ## Radius to find polar coordinates this line's endpoints 
     297        # Radius to find polar coordinates this line's endpoints 
    303298        self.radius = r 
    304         ## 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 
    305300        self.phi = phi 
    306         ## End points polar coordinates 
    307         x1 = self.radius * math.cos(self.theta) 
    308         y1 = self.radius * math.sin(self.theta) 
    309         x2 = -1 * self.radius * math.cos(self.theta) 
    310         y2 = -1 * self.radius * math.sin(self.theta) 
    311         ## 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 
    312307        self.inner_marker = self.axes.plot([x1 / 2.5], [y1 / 2.5], linestyle='', 
    313308                                           marker='s', markersize=10, 
     
    316311                                           zorder=zorder, visible=True)[0] 
    317312 
    318         ## Defining the current line 
     313        # Defining the current line 
    319314        self.line = self.axes.plot([x1, x2], [y1, y2], 
    320315                                   linestyle='-', marker='', 
    321316                                   color=self.color, visible=True)[0] 
    322         ## Flag to differentiate the left line from the right line motion 
     317        # Flag to differentiate the left line from the right line motion 
    323318        self.left_moving = False 
    324         ## Flag to define a motion 
     319        # Flag to define a motion 
    325320        self.has_move = False 
    326         ## connecting markers and draw the picture 
     321        # connecting markers and draw the picture 
    327322        self.connect_markers([self.inner_marker, self.line]) 
    328323 
     
    330325        """ 
    331326        Allow adding plot to the same panel 
    332  
    333327        :param n: the number of layer 
    334  
    335328        """ 
    336329        self.layernum = n 
     
    359352 
    360353        """ 
    361         #print "update left or right ", self.has_move 
    362354        self.left_moving = left 
    363355        theta3 = 0 
     
    367359            delta = 0 
    368360        if  right: 
    369             self.phi = -1 * math.fabs(self.phi) 
     361            self.phi = -1 * numpy.fabs(self.phi) 
    370362            #delta=-delta 
    371363        else: 
    372             self.phi = math.fabs(self.phi) 
     364            self.phi = numpy.fabs(self.phi) 
    373365        if side: 
    374366            self.theta = mline.theta + self.phi 
     
    383375        else: 
    384376            theta3 = self.theta2 + delta 
    385         x1 = self.radius * math.cos(theta3) 
    386         y1 = self.radius * math.sin(theta3) 
    387         x2 = -1 * self.radius * math.cos(theta3) 
    388         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) 
    389381        self.inner_marker.set(xdata=[x1 / 2.5], ydata=[y1 / 2.5]) 
    390382        self.line.set(xdata=[x1, x2], ydata=[y1, y2]) 
     
    396388        """ 
    397389        self.save_theta = self.theta 
    398         self.base.freeze_axes() 
    399390 
    400391    def moveend(self, ev): 
     
    414405        Process move to a new position, making sure that the move is allowed. 
    415406        """ 
    416         self.theta = math.atan2(y, x) 
     407        self.theta = numpy.arctan2(y, x) 
    417408        self.has_move = True 
    418         #ToDo: Simplify below 
    419409        if not self.left_moving: 
    420410            if  self.theta2 - self.theta <= 0 and self.theta2 > 0: 
     
    426416                return 
    427417            elif  self.theta2 < 0 and self.theta > 0 and \ 
    428                 (self.theta2 + 2 * math.pi - self.theta) >= math.pi / 2: 
     418                (self.theta2 + 2 * numpy.pi - self.theta) >= numpy.pi / 2: 
    429419                self.restore() 
    430420                return 
    431421            elif  self.theta2 < 0 and self.theta < 0 and \ 
    432                 (self.theta2 - self.theta) >= math.pi / 2: 
    433                 self.restore() 
    434                 return 
    435             elif self.theta2 > 0 and (self.theta2 - self.theta >= math.pi / 2 or \ 
    436                 (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)): 
    437427                self.restore() 
    438428                return 
    439429        else: 
    440             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: 
    441431                self.restore() 
    442432                return 
     
    447437                self.restore() 
    448438                return 
    449             elif self.theta - self.theta2 >= math.pi / 2 or  \ 
    450                 ((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 \ 
    451441                 self.theta < 0 and self.theta2 > 0): 
    452442                self.restore() 
    453443                return 
    454444 
    455         self.phi = math.fabs(self.theta2 - self.theta) 
    456         if self.phi > math.pi: 
    457             self.phi = 2 * math.pi - math.fabs(self.theta2 - self.theta) 
     445        self.phi = numpy.fabs(self.theta2 - self.theta) 
     446        if self.phi > numpy.pi: 
     447            self.phi = 2 * numpy.pi - numpy.fabs(self.theta2 - self.theta) 
    458448        self.base.base.update() 
    459449 
     
    464454        self.update() 
    465455 
    466     def get_params(self): 
     456    def getParams(self): 
    467457        """ 
    468458        """ 
     
    472462        return params 
    473463 
    474     def set_params(self, params): 
     464    def setParams(self, params): 
    475465        """ 
    476466        """ 
     
    484474    """ 
    485475    def __init__(self, base, axes, color='black', 
    486                  zorder=5, r=1.0, theta=math.pi / 4): 
     476                 zorder=5, r=1.0, theta=numpy.pi / 4): 
    487477        """ 
    488478        """ 
     
    496486        self.scale = 10.0 
    497487        # Inner circle 
    498         x1 = self.radius * math.cos(self.theta) 
    499         y1 = self.radius * math.sin(self.theta) 
    500         x2 = -1 * self.radius * math.cos(self.theta) 
    501         y2 = -1 * self.radius * math.sin(self.theta) 
     488        x1 = self.radius * numpy.cos(self.theta) 
     489        y1 = self.radius * numpy.sin(self.theta) 
     490        x2 = -1 * self.radius * numpy.cos(self.theta) 
     491        y2 = -1 * self.radius * numpy.sin(self.theta) 
    502492        # Inner circle marker 
    503493        self.inner_marker = self.axes.plot([x1 / 2.5], [y1 / 2.5], linestyle='', 
     
    540530        if theta != None: 
    541531            self.theta = theta 
    542         x1 = self.radius * math.cos(self.theta) 
    543         y1 = self.radius * math.sin(self.theta) 
    544         x2 = -1 * self.radius * math.cos(self.theta) 
    545         y2 = -1 * self.radius * math.sin(self.theta) 
     532        x1 = self.radius * numpy.cos(self.theta) 
     533        y1 = self.radius * numpy.sin(self.theta) 
     534        x2 = -1 * self.radius * numpy.cos(self.theta) 
     535        y2 = -1 * self.radius * numpy.sin(self.theta) 
    546536 
    547537        self.inner_marker.set(xdata=[x1 / 2.5], ydata=[y1 / 2.5]) 
     
    554544        """ 
    555545        self.save_theta = self.theta 
    556         self.base.freeze_axes() 
    557546 
    558547    def moveend(self, ev): 
     
    572561        Process move to a new position, making sure that the move is allowed. 
    573562        """ 
    574         self.theta = math.atan2(y, x) 
     563        self.theta = numpy.arctan2(y, x) 
    575564        self.has_move = True 
    576565        self.base.base.update() 
     
    582571        self.update() 
    583572 
    584     def get_params(self): 
     573    def getParams(self): 
    585574        """ 
    586575        """ 
     
    590579        return params 
    591580 
    592     def set_params(self, params): 
     581    def setParams(self, params): 
    593582        """ 
    594583        """ 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/boxSlicer.py

    rd85c194 r3bdbfcc  
    1 import wx 
    2 import math 
    31import numpy 
    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 
     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.GuiUtils as GuiUtils 
     8from sas.qtgui.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) 
     
    139123 
    140124        """ 
    141         if self.direction == None: 
     125        if self.direction is None: 
    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) 
    148  
    149         if nbins != None: 
     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) 
     132 
     133        if nbins is not None: 
    150134            self.nbins = nbins 
    151         if self.averager == None: 
    152             if new_slab == None: 
     135        if self.averager is None: 
     136            if new_slab is None: 
    153137                msg = "post data:cannot average , averager is empty" 
    154138                raise ValueError, msg 
     
    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 
    359         if x != None: 
    360             self.x = numpy.sign(self.x) * math.fabs(x) 
    361         if y != None: 
    362             self.y = numpy.sign(self.y) * math.fabs(y) 
    363         # # Draw lines and markers 
     324        # Reset x, y- coordinates if send as parameters 
     325        if x is not None: 
     326            self.x = numpy.sign(self.x) * numpy.fabs(x) 
     327        if y is not None: 
     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 
    466         if x != None: 
    467             self.x = numpy.sign(self.x) * math.fabs(x) 
    468         if y != None: 
    469             self.y = numpy.sign(self.y) * math.fabs(y) 
    470         # # draw lines and markers 
     425        # Reset x, y -coordinates if given as parameters 
     426        if x is not None: 
     427            self.x = numpy.sign(self.x) * numpy.fabs(x) 
     428        if y is not None: 
     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

    rd85c194 r3bdbfcc  
    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.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.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 != 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         if width != None: 
     492        # Save the new height, witdh of the rectangle if given as a param 
     493        if width is not None: 
    493494            self.half_width = width 
    494         if height != None: 
     495        if height is not None: 
    495496            self.half_height = height 
    496         # # If new  center coordinates are given draw the rectangle 
    497         # #given these value 
    498         if center != None: 
     497        # If new  center coordinates are given draw the rectangle 
     498        # given these value 
     499        if center is not None: 
    499500            self.center_x = center.x 
    500501            self.center_y = center.y 
     
    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 != None: 
     513        # if x1, y1, y2, y3 are given draw the rectangle with this value 
     514        if x1 is not None: 
    514515            self.x1 = x1 
    515         if x2 != None: 
     516        if x2 is not None: 
    516517            self.x2 = x2 
    517         if y1 != None: 
     518        if y1 is not None: 
    518519            self.y1 = y1 
    519         if y2 != None: 
     520        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 
    659         if width != None: 
     653        # Save the new height, witdh of the rectangle if given as a param 
     654        if width is not None: 
    660655            self.half_width = width 
    661         if height != None: 
     656        if height is not None: 
    662657            self.half_height = height 
    663         # # If new  center coordinates are given draw the rectangle 
    664         # #given these value 
    665         if center != None: 
     658        # If new  center coordinates are given draw the rectangle 
     659        # given these value 
     660        if center is not None: 
    666661            self.center_x = center.x 
    667662            self.center_y = center.y 
     
    678673                                 ydata=[self.y2, self.y2]) 
    679674            return 
    680         # # if x1, y1, y2, y3 are given draw the rectangle with this value 
    681         if x1 != None: 
     675        # if x1, y1, y2, y3 are given draw the rectangle with this value 
     676        if x1 is not None: 
    682677            self.x1 = x1 
    683         if x2 != None: 
     678        if x2 is not None: 
    684679            self.x2 = x2 
    685         if y1 != None: 
     680        if y1 is not None: 
    686681            self.y1 = y1 
    687         if y2 != None: 
     682        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.