<commit_before>

import wx
#import copy
#from copy import deepcopy
import math
import numpy
from sans.guiframe.events import NewPlotEvent
from sans.guiframe.events import StatusEvent
from sans.guiframe.events import SlicerParameterEvent
from sans.guiframe.events import EVT_SLICER_PARS
from BaseInteractor import _BaseInteractor
from sans.guiframe.dataFitting import Data1D
#import SlicerParameters


class BoxInteractor(_BaseInteractor):
    """
    BoxInteractor define a rectangle that return data1D average of Data2D
    in a rectangle area defined by -x, x ,y, -y
    """
    def __init__(self, base, axes, color='black', zorder=3):
        _BaseInteractor.__init__(self, base, axes, color=color)
        ## Class initialization
        self.markers = []
        self.axes = axes
        ##connecting artist
        self.connect = self.base.connect
        ## determine x y  values
        self.x = 0.5 * min(math.fabs(self.base.data2D.xmax),
                           math.fabs(self.base.data2D.xmin))
        self.y = 0.5 * min(math.fabs(self.base.data2D.xmax),
                           math.fabs(self.base.data2D.xmin))        
        ## when reach qmax reset the graph
        self.qmax = max(self.base.data2D.xmax, self.base.data2D.xmin,
                        self.base.data2D.ymax, self.base.data2D.ymin)   
        ## Number of points on the plot
        self.nbins = 30
        ## If True, I(|Q|) will be return, otherwise,
        #negative q-values are allowed
        self.fold = True        
        ## reference of the current  Slab averaging
        self.averager = None
        ## Create vertical and horizaontal lines for the rectangle
        self.vertical_lines = VerticalLines(self,
                                            self.base.subplot, 
                                            color='blue', 
                                            zorder=zorder,
                                            y=self.y ,
                                            x=self.x)
        self.vertical_lines.qmax = self.qmax
       
        self.horizontal_lines = HorizontalLines(self,
                                               self.base.subplot,
                                               color='green', 
                                               zorder=zorder,
                                               x=self.x,
                                               y=self.y)
        self.horizontal_lines.qmax = self.qmax
        ## draw the rectangle and plost the data 1D resulting
        ## of averaging data2D
        self.update()
        self._post_data()
        ## Bind to slice parameter events
        self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS)

    def _onEVT_SLICER_PARS(self, event):
        """
        receive an event containing parameters values to reset the slicer
        
        :param event: event of type SlicerParameterEvent with params as 
            attribute
        """
        wx.PostEvent(self.base.parent,
                     StatusEvent(status="BoxSlicer._onEVT_SLICER_PARS"))
        event.Skip()
        if event.type == self.__class__.__name__:
            self.set_params(event.params)
            self.base.update()
            
    def update_and_post(self):
        """
        Update the slicer and plot the resulting data
        """
        self.update()
        self._post_data()
        
    def set_layer(self, n):
        """
        Allow adding plot to the same panel
        
        :param n: the number of layer
        
        """
        self.layernum = n
        self.update()
        
    def clear(self):
        """
        Clear the slicer and all connected events related to this slicer
        """
        self.averager = None
        self.clear_markers()
        self.horizontal_lines.clear()
        self.vertical_lines.clear()
        self.base.connect.clearall()
        self.base.Unbind(EVT_SLICER_PARS)
        
    def update(self):
        """
        Respond to changes in the model by recalculating the profiles and
        resetting the widgets.
        """
        ##Update the slicer if an horizontal line is dragged   
        if self.horizontal_lines.has_move:
            self.horizontal_lines.update()
            self.vertical_lines.update(y=self.horizontal_lines.y)
        ##Update the slicer if a vertical line is dragged    
        if self.vertical_lines.has_move:
            self.vertical_lines.update()
            self.horizontal_lines.update(x=self.vertical_lines.x)
                 
    def save(self, ev):
        """
        Remember the roughness for this layer and the next so that we
        can restore on Esc.
        """
        self.base.freeze_axes()
        self.vertical_lines.save(ev)
        self.horizontal_lines.save(ev)
    
    def _post_data(self):
        pass
        
    def post_data(self, new_slab=None, nbins=None, direction=None):
        """
        post data averaging in Qx or Qy given new_slab type
        
        :param new_slab: slicer that determine with direction to average
        :param nbins: the number of points plotted when averaging
        :param direction: the direction of averaging
        
        """
        x_min = -1 * math.fabs(self.vertical_lines.x)
        x_max = math.fabs(self.vertical_lines.x)
        y_min = -1 * math.fabs(self.horizontal_lines.y)
        y_max = math.fabs(self.horizontal_lines.y)
        
        if nbins != None:
            self.nbins = nbins
        if self.averager == None:
            if new_slab == None:
                msg = "post data:cannot average , averager is empty"
                raise ValueError, msg
            self.averager = new_slab
        if direction == "X":
            if self.fold:
                x_low = 0
            else:
                x_low = math.fabs(x_min)
            bin_width = (x_max + x_low)/self.nbins
        else:
            if self.fold:
                y_low = 0
            else:
                y_low = math.fabs(y_min)
            bin_width = (y_max + y_low)/self.nbins
        ## Average data2D given Qx or Qy
        box = self.averager(x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max,
                         bin_width=bin_width)
        box.fold = self.fold
        boxavg = box(self.base.data2D)
        #3 Create Data1D to plot<commit_msg>I modified boxSlicer to fix the issue outlined in Trac ticket #210. More details are available in the ticket.<commit_after>

import wx
#import copy
#from copy import deepcopy
import math
import numpy
from sans.guiframe.events import NewPlotEvent
from sans.guiframe.events import StatusEvent
from sans.guiframe.events import SlicerParameterEvent
from sans.guiframe.events import EVT_SLICER_PARS
from BaseInteractor import _BaseInteractor
from sans.guiframe.dataFitting import Data1D
#import SlicerParameters


class BoxInteractor(_BaseInteractor):
    """
    BoxInteractor define a rectangle that return data1D average of Data2D
    in a rectangle area defined by -x, x ,y, -y
    """
    def __init__(self, base, axes, color='black', zorder=3):
        _BaseInteractor.__init__(self, base, axes, color=color)
        ## Class initialization
        self.markers = []
        self.axes = axes
        ##connecting artist
        self.connect = self.base.connect
        ## which direction is the preferred interaction direction
        self.direction = None
        ## determine x y  values
        self.x = 0.5 * min(math.fabs(self.base.data2D.xmax),
                           math.fabs(self.base.data2D.xmin))
        self.y = 0.5 * min(math.fabs(self.base.data2D.xmax),
                           math.fabs(self.base.data2D.xmin))        
        ## when reach qmax reset the graph
        self.qmax = max(self.base.data2D.xmax, self.base.data2D.xmin,
                        self.base.data2D.ymax, self.base.data2D.ymin)   
        ## Number of points on the plot
        self.nbins = 30
        ## If True, I(|Q|) will be return, otherwise,
        #negative q-values are allowed
        self.fold = True        
        ## reference of the current  Slab averaging
        self.averager = None
        ## Create vertical and horizaontal lines for the rectangle
        self.vertical_lines = VerticalLines(self,
                                            self.base.subplot, 
                                            color='blue', 
                                            zorder=zorder,
                                            y=self.y ,
                                            x=self.x)
        self.vertical_lines.qmax = self.qmax
       
        self.horizontal_lines = HorizontalLines(self,
                                               self.base.subplot,
                                               color='green', 
                                               zorder=zorder,
                                               x=self.x,
                                               y=self.y)
        self.horizontal_lines.qmax = self.qmax
        ## draw the rectangle and plost the data 1D resulting
        ## of averaging data2D
        self.update()
        self._post_data()
        ## Bind to slice parameter events
        self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS)

    def _onEVT_SLICER_PARS(self, event):
        """
        receive an event containing parameters values to reset the slicer
        
        :param event: event of type SlicerParameterEvent with params as 
            attribute
        """
        wx.PostEvent(self.base.parent,
                     StatusEvent(status="BoxSlicer._onEVT_SLICER_PARS"))
        event.Skip()
        if event.type == self.__class__.__name__:
            self.set_params(event.params)
            self.base.update()
            
    def update_and_post(self):
        """
        Update the slicer and plot the resulting data
        """
        self.update()
        self._post_data()
        
    def set_layer(self, n):
        """
        Allow adding plot to the same panel
        
        :param n: the number of layer
        
        """
        self.layernum = n
        self.update()
        
    def clear(self):
        """
        Clear the slicer and all connected events related to this slicer
        """
        self.averager = None
        self.clear_markers()
        self.horizontal_lines.clear()
        self.vertical_lines.clear()
        self.base.connect.clearall()
        self.base.Unbind(EVT_SLICER_PARS)
        
    def update(self):
        """
        Respond to changes in the model by recalculating the profiles and
        resetting the widgets.
        """
        ##Update the slicer if an horizontal line is dragged   
        if self.horizontal_lines.has_move:
            self.horizontal_lines.update()
            self.vertical_lines.update(y=self.horizontal_lines.y)
        ##Update the slicer if a vertical line is dragged    
        if self.vertical_lines.has_move:
            self.vertical_lines.update()
            self.horizontal_lines.update(x=self.vertical_lines.x)
                 
    def save(self, ev):
        """
        Remember the roughness for this layer and the next so that we
        can restore on Esc.
        """
        self.base.freeze_axes()
        self.vertical_lines.save(ev)
        self.horizontal_lines.save(ev)
    
    def _post_data(self):
        pass
        
    def post_data(self, new_slab=None, nbins=None, direction=None):
        """
        post data averaging in Qx or Qy given new_slab type
        
        :param new_slab: slicer that determine with direction to average
        :param nbins: the number of points plotted when averaging
        :param direction: the direction of averaging
        
        """
        if self.direction == None:
            self.direction = direction
            
        x_min = -1 * math.fabs(self.vertical_lines.x)
        x_max = math.fabs(self.vertical_lines.x)
        y_min = -1 * math.fabs(self.horizontal_lines.y)
        y_max = math.fabs(self.horizontal_lines.y)
        
        if nbins != None:
            self.nbins = nbins
        if self.averager == None:
            if new_slab == None:
                msg = "post data:cannot average , averager is empty"
                raise ValueError, msg
            self.averager = new_slab
        if self.direction == "X":
            if self.fold:
                x_low = 0
            else:
                x_low = math.fabs(x_min)
            bin_width = (x_max + x_low)/self.nbins
        elif self.direction == "Y":
            if self.fold:
                y_low = 0
            else:
                y_low = math.fabs(y_min)
            bin_width = (y_max + y_low)/self.nbins
        else:
            msg = "post data:no Box Average direction was supplied"
            raise ValueError, msg
        ## Average data2D given Qx or Qy
        box = self.averager(x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max,
                         bin_width=bin_width)
        box.fold = self.fold
        boxavg = box(self.base.data2D)
        #3 Create Data1D to plot
{'fraction_non_alphanumeric': 0.07967914438502674, 'fraction_numerical': 0.004507257448433919, 'mean_word_length': 1.5563366529974614, 'pattern_counts': {'":': 3, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 40, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6958390', 'n_tokens_mistral': 3669, 'n_tokens_neox': 3565, 'n_words': 935}