sas.qtgui.Plotting.Slicers package

Submodules

sas.qtgui.Plotting.Slicers.AnnulusSlicer module

class sas.qtgui.Plotting.Slicers.AnnulusSlicer.AnnulusInteractor(base, axes, item=None, color='black', zorder=3)

Bases: BaseInteractor, SlicerModel, StackableMixin

AnnulusInteractor plots a data1D average of an annulus area defined in a Data2D object. The data1D averaging itself is performed in sasdata by manipulations.py

This class uses the RingInteractor class to define two rings of radius r1 and r2 (Q1 and Q2). All Q points at a constant angle phi from the x-axis are averaged together to provide a 1D array in phi from 0 to 180 degrees.

__annotations__ = {}
__doc__ = '\nAnnulusInteractor plots a data1D average of an annulus area defined in a\nData2D object. The data1D averaging itself is performed in sasdata by\nmanipulations.py\n\nThis class uses the RingInteractor class to define two rings of radius\nr1 and r2 (Q1 and Q2). All Q points at a constant angle phi from the x-axis\nare averaged together to provide a 1D array in phi from 0 to 180 degrees.\n'
__firstlineno__ = 14
__init__(base, axes, item=None, color='black', zorder=3)
__module__ = 'sas.qtgui.Plotting.Slicers.AnnulusSlicer'
__static_attributes__ = ('_item', '_plot_id', 'axes', 'base', 'connect', 'dqmin', 'inner_circle', 'layernum', 'markers', 'nbins', 'outer_circle', 'qmax', 'sign', 'xmaxd', 'xmind')
_get_slicer_type_id()

Return the slicer type identifier

_post_data(nbins=None)

Uses annulus parameters to plot averaged data into 1D data.

Parameters:

nbins – the number of points to plot

clear()

Clear the slicer and all connected events related to this slicer

draw()
getParams()

Store a copy of values of parameters of the slicer into a dictionary. :return params: the dictionary created

move(x, y, ev)

Process move to a new position, making sure that the move is allowed.

moveend(ev)

Called when any dragging motion ends. Redraw the plot with new parameters.

restore(ev)

Restore the roughness for this layer.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc.

setParams(params)

Receive a dictionary and reset the slicer with values contained in the values of the dictionary.

Parameters:

params – a dictionary containing name of slicer parameters and values the user assigned to the slicer.

set_cursor(x, y)
set_layer(n)

Allow adding plot to the same panel :param n: the number of layer

update()

Respond to changes in the model by recalculating the profiles and resetting the widgets.

validate(param_name, param_value)

Test the proposed new value “value” for row “row” of parameters

class sas.qtgui.Plotting.Slicers.AnnulusSlicer.RingInteractor(base, axes, color='black', zorder=5, r=1.0, sign=1)

Bases: BaseInteractor

Draw a ring on a data2D plot centered at (0,0) given a radius

__annotations__ = {}
__doc__ = '\nDraw a ring on a data2D plot centered at (0,0) given a radius\n'
__firstlineno__ = 256
__init__(base, axes, color='black', zorder=5, r=1.0, sign=1)
Param:

the color of the line that defined the ring

Parameters:
  • r – the radius of the ring

  • sign – the direction of motion the marker

__module__ = 'sas.qtgui.Plotting.Slicers.AnnulusSlicer'
__static_attributes__ = ('_inner_mouse_x', '_inner_mouse_y', '_inner_save_x', '_inner_save_y', 'axes', 'base', 'inner_circle', 'inner_marker', 'layernum', 'markers', 'npts', 'sign')
clear()

Clear the slicer and all connected events related to this slicer

getParams()

Store a copy of values of parameters of the slicer into a dictionary. :return params: the dictionary created

get_radius()
Return self._inner_mouse_x:

the current radius of the ring

move(x, y, ev)

Process move to a new position, making sure that the move is allowed.

moveend(ev)

Called after a dragging motion

restore(ev)

Restore the roughness for this layer.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc.

setParams(params)

Receive a dictionary and reset the slicer with values contained in the values of the dictionary.

Parameters:

params – a dictionary containing name of slicer parameters and values the user assigned to the slicer.

set_cursor(x, y)

draw the ring given x, y value

set_layer(n)

Allow adding plot to the same panel

Parameters:

n – the number of layer

update()

Draw the new roughness on the graph.

sas.qtgui.Plotting.Slicers.ArcInteractor module

class sas.qtgui.Plotting.Slicers.ArcInteractor.ArcInteractor(base, axes, color='black', zorder=5, r=1.0, theta=1.0471975511965976, phi=0.39269908169872414)

Bases: BaseInteractor

Draw an arc on a data2D plot with a variable radius (centered at [0,0]). User interaction adjusts the parameter r

param r: radius from (0,0) of the arc on a data2D plot param theta: angle from x-axis of the central point on the arc param phi: angle from the centre point on the arc to each of its edges

__annotations__ = {}
__doc__ = '\nDraw an arc on a data2D plot with a variable radius (centered at [0,0]).\nUser interaction adjusts the parameter r\n\nparam r: radius from (0,0) of the arc on a data2D plot\nparam theta: angle from x-axis of the central point on the arc\nparam phi: angle from the centre point on the arc to each of its edges\n'
__firstlineno__ = 6
__init__(base, axes, color='black', zorder=5, r=1.0, theta=1.0471975511965976, phi=0.39269908169872414)
__module__ = 'sas.qtgui.Plotting.Slicers.ArcInteractor'
__static_attributes__ = ('_mouse_x', '_mouse_y', '_save_x', '_save_y', 'arc', 'axes', 'color', 'has_move', 'layernum', 'marker', 'markers', 'npts', 'phi', 'radius', 'scale', 'theta')
clear()

Clear this slicer and its markers

move(x, y, ev)

Process move to a new position.

moveend(ev)

After a dragging motion reset the flag self.has_move to False :param ev: event

restore(ev)

Restore the roughness for this layer.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc.

set_cursor(x, y)
set_layer(n)

Allow adding plot to the same panel :param n: the number of layer

update(theta=None, phi=None, r=None)

Draw the new roughness on the graph. :param theta: angle from x-axis of the central point on the arc :param phi: angle from the centre point on the arc to each of its edges :param r: radius from (0,0) of the arc on a data2D plot

sas.qtgui.Plotting.Slicers.BaseInteractor module

class sas.qtgui.Plotting.Slicers.BaseInteractor.BaseInteractor(base, axes, color='black')

Bases: object

Share some functions between the interface interactor and various layer interactors.

Individual interactors need the following functions:

save(ev) - save the current state for later restore restore() - restore the old state move(x,y,ev) - move the interactor to position x,y moveend(ev) - end the drag event update() - draw the interactors

The following are provided by the base class:

connect_markers(markers) - register callbacks for all markers clear_markers() - remove all items in self.markers onHilite(ev) - enter/leave event processing onLeave(ev) - enter/leave event processing onClick(ev) - mouse click: calls save() onRelease(ev) - mouse click ends: calls moveend() onDrag(ev) - mouse move: calls move() or restore() onKey(ev) - keyboard move: calls move() or restore()

Interactor attributes:

base - model we are operating on axes - axes holding the interactor color - color of the interactor in non-active state markers - list of handles for the interactor

__annotations__ = {}
__dict__ = mappingproxy({'__module__': 'sas.qtgui.Plotting.Slicers.BaseInteractor', '__firstlineno__': 15, '__doc__': '\nShare some functions between the interface interactor and various layer\ninteractors.\n\nIndividual interactors need the following functions:\n\n    save(ev)  - save the current state for later restore\n    restore() - restore the old state\n    move(x,y,ev) - move the interactor to position x,y\n    moveend(ev) - end the drag event\n    update() - draw the interactors\n\nThe following are provided by the base class:\n\n    connect_markers(markers) - register callbacks for all markers\n    clear_markers() - remove all items in self.markers\n    onHilite(ev) - enter/leave event processing\n    onLeave(ev) - enter/leave event processing\n    onClick(ev) - mouse click: calls save()\n    onRelease(ev) - mouse click ends: calls moveend()\n    onDrag(ev) - mouse move: calls move() or restore()\n    onKey(ev) - keyboard move: calls move() or restore()\n\nInteractor attributes:\n\n    base  - model we are operating on\n    axes  - axes holding the interactor\n    color - color of the interactor in non-active state\n    markers - list of handles for the interactor\n\n', '__init__': <function BaseInteractor.__init__>, 'clear_markers': <function BaseInteractor.clear_markers>, 'save': <function BaseInteractor.save>, 'restore': <function BaseInteractor.restore>, 'move': <function BaseInteractor.move>, 'moveend': <function BaseInteractor.moveend>, 'connect_markers': <function BaseInteractor.connect_markers>, 'onHilite': <function BaseInteractor.onHilite>, 'onLeave': <function BaseInteractor.onLeave>, 'onClick': <function BaseInteractor.onClick>, 'onRelease': <function BaseInteractor.onRelease>, 'onDrag': <function BaseInteractor.onDrag>, 'onKey': <function BaseInteractor.onKey>, 'dpixel': <function BaseInteractor.dpixel>, '__static_attributes__': ('axes', 'base', 'clickx', 'clicky', 'color', 'data', 'markers'), '__dict__': <attribute '__dict__' of 'BaseInteractor' objects>, '__weakref__': <attribute '__weakref__' of 'BaseInteractor' objects>, '__annotations__': {}})
__doc__ = '\nShare some functions between the interface interactor and various layer\ninteractors.\n\nIndividual interactors need the following functions:\n\n    save(ev)  - save the current state for later restore\n    restore() - restore the old state\n    move(x,y,ev) - move the interactor to position x,y\n    moveend(ev) - end the drag event\n    update() - draw the interactors\n\nThe following are provided by the base class:\n\n    connect_markers(markers) - register callbacks for all markers\n    clear_markers() - remove all items in self.markers\n    onHilite(ev) - enter/leave event processing\n    onLeave(ev) - enter/leave event processing\n    onClick(ev) - mouse click: calls save()\n    onRelease(ev) - mouse click ends: calls moveend()\n    onDrag(ev) - mouse move: calls move() or restore()\n    onKey(ev) - keyboard move: calls move() or restore()\n\nInteractor attributes:\n\n    base  - model we are operating on\n    axes  - axes holding the interactor\n    color - color of the interactor in non-active state\n    markers - list of handles for the interactor\n\n'
__firstlineno__ = 15
__init__(base, axes, color='black')
__module__ = 'sas.qtgui.Plotting.Slicers.BaseInteractor'
__static_attributes__ = ('axes', 'base', 'clickx', 'clicky', 'color', 'data', 'markers')
__weakref__

list of weak references to the object

clear_markers()

Clear old markers and interfaces.

connect_markers(markers)

Connect markers to callbacks

dpixel(x, y, nudge=False)

Return the step size in data coordinates for a small step in screen coordinates. If nudge is False (default) the step size is one pixel. If nudge is True, the step size is 0.2 pixels.

move(x, y, ev)
moveend(ev)
onClick(ev)

Prepare to move the artist. Calls save() to preserve the state for later restore(). Also notify plotter of slicer interaction.

onDrag(ev)

Move the artist. Calls move() to update the state, or restore() if the mouse leaves the window.

onHilite(ev)

Hilite the artist reporting the event, indicating that it is ready to receive a click.

onKey(ev)

Respond to keyboard events. Arrow keys move the widget. Escape restores it to the position before the last click.

Calls move() to update the state. Calls restore() on escape.

onLeave(ev)

Restore the artist to the original colour when the cursor leaves.

onRelease(ev)

Notify plotter on end of interaction.

restore(ev)
save(ev)

sas.qtgui.Plotting.Slicers.BoxSlicer module

class sas.qtgui.Plotting.Slicers.BoxSlicer.BoxInteractor(base, axes, item=None, color='black', zorder=3, direction=None)

Bases: BaseInteractor, SlicerModel, StackableMixin

BoxInteractor plots a data1D average of a rectangular area defined in a Data2D object. The data1D averaging itself is performed in sasdata by manipulations.py

This class uses two other classes, HorizontalLines and VerticalLines, to define the rectangle area: x1, x2 ,y1, y2. It is subclassed by BoxInteractorX and BoxInteracgtorY which define the direction of the average. BoxInteractorX averages all the points from y1 to y2 as a function of Q_x and BoxInteractorY averages all the points from x1 to x2 as a function of Q_y

__annotations__ = {}
__doc__ = '\nBoxInteractor plots a data1D average of a rectangular area defined in\na Data2D object. The data1D averaging itself is performed in sasdata\nby manipulations.py\n\nThis class uses two other classes, HorizontalLines and VerticalLines,\nto define the rectangle area: x1, x2 ,y1, y2. It is subclassed by\nBoxInteractorX and BoxInteracgtorY which define the direction of the\naverage. BoxInteractorX averages all the points from y1 to y2 as a\nfunction of Q_x and BoxInteractorY averages all the points from\nx1 to x2 as a function of Q_y\n'
__firstlineno__ = 13
__init__(base, axes, item=None, color='black', zorder=3, direction=None)
__module__ = 'sas.qtgui.Plotting.Slicers.BoxSlicer'
__static_attributes__ = ('_item', '_plot_id', 'averager', 'axes', 'center', 'center_x', 'center_y', 'connect', 'direction', 'fold', 'half_height', 'half_width', 'has_move', 'horizontal_lines', 'layernum', 'markers', 'nbins', 'vertical_lines')
_get_slicer_type_id()

Get the type identifier for this slicer. Should be overridden by subclasses to return something like “AnnulusPhi” + data.name

Returns:

String identifying the slicer type and source data

_post_data(new_slab=None, nbins=None, direction=None)

post 1D data averaging in Qx or Qy given new_slab type

Parameters:
  • new_slab – slicer that determine with direction to average

  • nbins – the number of points plotted when averaging

  • direction – the direction of averaging

clear()

Clear the slicer and all connected events related to this slicer

draw()

Draws the Canvas using the canvas.Draw from the calling class that instantiated this object.

getParams()

Store a copy of values of parameters of the slicer into a dictionary.

Return params:

the dictionary created

move(x, y, ev)

Process move to a new position, making sure that the move is allowed.

moveend(ev)

Called after a dragging event. Post the slicer new parameters and creates a new Data1D corresponding to the new average

restore(ev)

Restore the roughness for this layer. Only restores things that have moved. Otherwise you are restoring too far back.

Save is only done when the mouse is clicked not when it is released. Thus, if vertical lines have changed, they will move horizontal lines also, but the original state of those horizontal lines has not been saved (there was no click event on the horizontal lines). However, restoring the vertical lines and then doing an updated will take care of the related values in horizontal lines.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc.

setParams(params)

Receive a dictionary and reset the slicer with values contained in the values of the dictionary.

Parameters:

params – a dictionary containing name of slicer parameters and values the user assigned to the slicer.

set_cursor(x, y)
set_layer(n)

Allow adding plot to the same panel

Parameters:

n – the number of layer

update()

Respond to changes in the model by recalculating the profiles and resetting the widgets.

update_and_post()

Update the slicer and plot the resulting data

validate(param_name, param_value)

Validate input from user.

Values get checked at apply time:

  • nbins cannot be zero or smaller

  • The full ROI should stay within the data. Thus center_x and center_y are restricted such that the center +/- width (or height) cannot be greater or smaller than data max/min.

  • The width/height should not be set so small as to leave no data in the ROI. Here we only make sure that the width/height is not zero as done when dragging the vertical or horizontal lines. We let the call to _post_data capture the ValueError of no points in ROI raised by manipulations.py, log the message and negate the entry at that point.

class sas.qtgui.Plotting.Slicers.BoxSlicer.BoxInteractorX(base, axes, item=None, color='black', zorder=3)

Bases: BoxInteractor

Average in Qx direction. The data for all Qy at a constant Qx are averaged together to provide a 1D array in Qx (to be plotted as a function of Qx)

__annotations__ = {}
__doc__ = '\nAverage in Qx direction. The data for all Qy at a constant Qx are\naveraged together to provide a 1D array in Qx (to be plotted as a function\nof Qx)\n'
__firstlineno__ = 952
__init__(base, axes, item=None, color='black', zorder=3)
__module__ = 'sas.qtgui.Plotting.Slicers.BoxSlicer'
__static_attributes__ = ('base',)
_post_data(new_slab=None, nbins=None, direction=None)

Post data creating by averaging in Qx direction

class sas.qtgui.Plotting.Slicers.BoxSlicer.BoxInteractorY(base, axes, item=None, color='black', zorder=3)

Bases: BoxInteractor

Average in Qy direction. The data for all Qx at a constant Qy are averaged together to provide a 1D array in Qy (to be plotted as a function of Qy)

__annotations__ = {}
__doc__ = '\nAverage in Qy direction. The data for all Qx at a constant Qy are\naveraged together to provide a 1D array in Qy (to be plotted as a function\nof Qy)\n'
__firstlineno__ = 972
__init__(base, axes, item=None, color='black', zorder=3)
__module__ = 'sas.qtgui.Plotting.Slicers.BoxSlicer'
__static_attributes__ = ('base',)
_post_data(new_slab=None, nbins=None, direction=None)

Post data creating by averaging in Qy direction

class sas.qtgui.Plotting.Slicers.BoxSlicer.HorizontalDoubleLine(base, axes, color='black', zorder=5, half_width=0.5, half_height=0.5, center_x=0.0, center_y=0.0)

Bases: BaseInteractor

Draw 2 vertical lines that can move symmetrically in opposite directions in y and centered on a point (PointInteractor). It also defines the left and right x positions of a box.

__annotations__ = {}
__doc__ = '\nDraw 2 vertical lines that can move symmetrically in opposite directions in y and centered on\na point (PointInteractor). It also defines the left and right x positions of a box.\n'
__firstlineno__ = 763
__init__(base, axes, color='black', zorder=5, half_width=0.5, half_height=0.5, center_x=0.0, center_y=0.0)
__module__ = 'sas.qtgui.Plotting.Slicers.BoxSlicer'
__static_attributes__ = ('axes', 'bottom_line', 'center_x', 'center_y', 'color', 'half_height', 'half_width', 'has_move', 'layernum', 'markers', 'save_half_height', 'save_half_width', 'save_x1', 'save_x2', 'save_y1', 'save_y2', 'top_line', 'top_marker', 'valid_move', 'x1', 'x2', 'y1', 'y2')
clear()

Clear this figure and its markers

move(x, y, ev)

Process move to a new position, making sure that the move is allowed. In principle, the move must not create a box without any data points in it. For the dragging (continuous move), we make sure that the width or height are not negative and that the entire ROI resides withing the data. We leave the check of whether there are any data in that ROI to the manipulations.py which is called from _post_data, itself being called on moveend(ev).

moveend(ev)

After a dragging motion update the 1D average plot and then reset the flag self.has_move to False.

restore(ev)

Restore the roughness for this layer.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc. This save is run on mouse click (not a drag event) by BaseInteractor

setCursor(x, y)

Update the figure given x and y

setLayer(n)

Allow adding plot to the same panel @param n: the number of layer

update(x1=None, x2=None, y1=None, y2=None, half_width=None, half_height=None, center=None)

Draw the new roughness on the graph. :param x1: new maximum value of x coordinates :param x2: new minimum value of x coordinates :param y1: new maximum value of y coordinates :param y2: new minimum value of y coordinates :param half_width: is the half width of the new rectangle :param half_height: is the half height of the new rectangle :param center: provided x, y coordinates of the center point

class sas.qtgui.Plotting.Slicers.BoxSlicer.PointInteractor(base, axes, color='black', zorder=5, center_x=0.0, center_y=0.0)

Bases: BaseInteractor

Draw a point that can be dragged with the marker. this class controls the motion the center of the BoxSum

__annotations__ = {}
__doc__ = '\nDraw a point that can be dragged with the marker.\nthis class controls the motion the center of the BoxSum\n'
__firstlineno__ = 452
__init__(base, axes, color='black', zorder=5, center_x=0.0, center_y=0.0)
__module__ = 'sas.qtgui.Plotting.Slicers.BoxSlicer'
__static_attributes__ = ('axes', 'center', 'center_marker', 'has_move', 'layernum', 'markers', 'save_x', 'save_y', 'valid_move', 'x', 'y')
clear()

Clear this figure and its markers

move(x, y, ev)

Process move to a new position. BaseInteractor checks that the center is within the data. Here we check to make sure that the center move does not cause any part of the ROI box to move outside the data.

moveend(ev)
restore(ev)

Restore the roughness for this layer.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc.

setCursor(x, y)
..todo:: the cursor moves are currently being captured somewhere upstream

of BaseInteractor so this never gets called.

setLayer(n)

Allow adding plot to the same panel @param n: the number of layer

update(center_x=None, center_y=None)

Draw the new roughness on the graph.

class sas.qtgui.Plotting.Slicers.BoxSlicer.VerticalDoubleLine(base, axes, color='black', zorder=5, half_width=0.5, half_height=0.5, center_x=0.0, center_y=0.0)

Bases: BaseInteractor

Draw 2 vertical lines that can move symmetrically in opposite directions in x and centered on a point (PointInteractor). It also defines the top and bottom y positions of a box.

__annotations__ = {}
__doc__ = '\nDraw 2 vertical lines that can move symmetrically in opposite directions in x and centered on\na point (PointInteractor). It also defines the top and bottom y positions of a box.\n'
__firstlineno__ = 572
__init__(base, axes, color='black', zorder=5, half_width=0.5, half_height=0.5, center_x=0.0, center_y=0.0)
__module__ = 'sas.qtgui.Plotting.Slicers.BoxSlicer'
__static_attributes__ = ('axes', 'center_x', 'center_y', 'color', 'half_height', 'half_width', 'has_move', 'layernum', 'left_line', 'markers', 'right_line', 'right_marker', 'save_half_height', 'save_half_width', 'save_x1', 'save_x2', 'save_y1', 'save_y2', 'valid_move', 'x1', 'x2', 'y1', 'y2')
clear()

Clear this slicer and its markers

move(x, y, ev)

Process move to a new position, making sure that the move is allowed. In principle, the move must not create a box without any data points in it. For the dragging (continuous move), we make sure that the width or height are not negative and that the entire ROI resides withing the data. We leave the check of whether there are any data in that ROI to the manipulations.py which is called from _post_data, itself being called on moveend(ev).

moveend(ev)

After a dragging motion update the 1D average plot and then reset the flag self.has_move to False.

restore(ev)

Restore the roughness for this layer.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc. This save is run on mouse click (not a drag event) by BaseInteractor

setCursor(x, y)

Update the figure given x and y

setLayer(n)

Allow adding plot to the same panel :param n: the number of layer

update(x1=None, x2=None, y1=None, y2=None, half_width=None, half_height=None, center=None)

Draw the new roughness on the graph. :param x1: new maximum value of x coordinates :param x2: new minimum value of x coordinates :param y1: new maximum value of y coordinates :param y2: new minimum value of y coordinates :param half_width: is the half width of the new rectangle :param half_height: is the half height of the new rectangle :param center: provided x, y coordinates of the center point

sas.qtgui.Plotting.Slicers.BoxSum module

class sas.qtgui.Plotting.Slicers.BoxSum.BoxSumCalculator(base, axes, color='black', zorder=3)

Bases: BaseInteractor

BoxSumCalculator Class computes properties (such as sum and average of intensities) from a rectangular area defined in a data2D object. The actual calculations are done by manipulations.py

This class uses three other classes, PointerInteractor to define the center of the rectangle, and VerticalDoubleLine and HorizontalDoubleLine to define the rectangle x1,x2,y1,y2.

..TODO: the 3 classes here are the same as used by the BoxSlicer. These

should probably be abstracted out.

@param zorder: Artists with lower zorder values are drawn first. @param x_min: the minimum value of the x coordinate @param x_max: the maximum value of the x coordinate @param y_min: the minimum value of the y coordinate @param y_max: the maximum value of the y coordinate

__annotations__ = {}
__doc__ = '\nBoxSumCalculator Class computes properties (such as sum and average of\nintensities) from a rectangular area defined in a data2D object. The actual\ncalculations are done by manipulations.py\n\nThis class uses three other classes, PointerInteractor to define the center\nof the rectangle, and VerticalDoubleLine and HorizontalDoubleLine to define\nthe rectangle x1,x2,y1,y2.\n\n..TODO: the 3 classes here are the same as used by the BoxSlicer. These\n        should probably be abstracted out.\n\n@param zorder:  Artists with lower zorder values are drawn first.\n@param x_min: the minimum value of the x coordinate\n@param x_max: the maximum value of the x coordinate\n@param y_min: the minimum value of the y coordinate\n@param y_max: the maximum value of the y coordinate\n\n'
__firstlineno__ = 13
__init__(base, axes, color='black', zorder=3)
__module__ = 'sas.qtgui.Plotting.Slicers.BoxSum'
__static_attributes__ = ('_model', 'axes', 'center', 'center_x', 'center_y', 'connect', 'count', 'error', 'has_move', 'horizontal_lines', 'layernum', 'markers', 'nbins', 'panel_name', 'points', 'qmax', 'total', 'totalerror', 'update_model', 'vertical_lines', 'widget', 'xmax', 'xmin', 'ymax', 'ymin')
clear()

Clear the slicer and all connected events related to this slicer

draw()

Redraw canvas

getParams()

Store a copy of values of parameters of the slicer into a dictionary. :return params: the dictionary created

getResult()

Return the result of box summation

model()

model accessor

moveend(ev)

After a dragging motion this function is called to compute the error and the sum of pixel of a given data 2D

postData()

Get the limits of the boxsum and compute the sum of the pixel contained in that region and the error on that sum

restore(ev)

Restore the roughness for this layer.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc.

setLayer(n)

Allow adding plot to the same panel :param n: the number of layer

setModelFromParams()

Set up the Qt model for data handling between controls

setPanelName(name)

Store the name of the panel associated to this slicer @param name: the name of this panel

setParams(params)

Receive a dictionary and reset the slicer with values contained in the values of the dictionary. :param params: a dictionary containing name of slicer parameters and values the user assigned to the slicer.

setParamsFromModel()

Cast model content onto params dict

setReadOnlyParametersFromModel()

Cast model content onto “read-only” subset of parameters

update()

Respond to changes in the model by recalculating the profiles and resetting the widgets.

validate(param_name, param_value)

Validate input from user

class sas.qtgui.Plotting.Slicers.BoxSum.HorizontalDoubleLine(base, axes, color='black', zorder=5, x=0.5, y=0.5, center_x=0.0, center_y=0.0)

Bases: BaseInteractor

Draw 2 horizontal lines moving in opposite direction and centered on a point (PointInteractor)

__annotations__ = {}
__doc__ = '\nDraw 2 horizontal lines moving in opposite direction and centered on\na point (PointInteractor)\n'
__firstlineno__ = 584
__init__(base, axes, color='black', zorder=5, x=0.5, y=0.5, center_x=0.0, center_y=0.0)
__module__ = 'sas.qtgui.Plotting.Slicers.BoxSum'
__static_attributes__ = ('axes', 'bottom_line', 'center_x', 'center_y', 'color', 'half_height', 'half_width', 'has_move', 'layernum', 'markers', 'save_half_height', 'save_half_width', 'save_x1', 'save_x2', 'save_y1', 'save_y2', 'top_line', 'top_marker', 'x1', 'x2', 'y1', 'y2')
clear()

Clear this figure and its markers

move(x, y, ev)

Process move to a new position, making sure that the move is allowed.

moveend(ev)

After a dragging motion reset the flag self.has_move to False

restore(ev)

Restore the roughness for this layer.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc.

setCursor(x, y)

Update the figure given x and y

setLayer(n)

Allow adding plot to the same panel @param n: the number of layer

update(x1=None, x2=None, y1=None, y2=None, width=None, height=None, center=None)

Draw the new roughness on the graph. :param x1: new maximum value of x coordinates :param x2: new minimum value of x coordinates :param y1: new maximum value of y coordinates :param y2: new minimum value of y coordinates :param width: is the width of the new rectangle :param height: is the height of the new rectangle :param center: provided x, y coordinates of the center point

class sas.qtgui.Plotting.Slicers.BoxSum.PointInteractor(base, axes, color='black', zorder=5, center_x=0.0, center_y=0.0)

Bases: BaseInteractor

Draw a point that can be dragged with the marker. this class controls the motion the center of the BoxSum

__annotations__ = {}
__doc__ = '\nDraw a point that can be dragged with the marker.\nthis class controls the motion the center of the BoxSum\n'
__firstlineno__ = 309
__init__(base, axes, color='black', zorder=5, center_x=0.0, center_y=0.0)
__module__ = 'sas.qtgui.Plotting.Slicers.BoxSum'
__static_attributes__ = ('axes', 'center', 'center_marker', 'has_move', 'layernum', 'markers', 'save_x', 'save_y', 'x', 'y')
clear()

Clear this figure and its markers

move(x, y, ev)

Process move to a new position, making sure that the move is allowed.

moveend(ev)
restore(ev)

Restore the roughness for this layer.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc.

setCursor(x, y)
setLayer(n)

Allow adding plot to the same panel @param n: the number of layer

update(center_x=None, center_y=None)

Draw the new roughness on the graph.

class sas.qtgui.Plotting.Slicers.BoxSum.VerticalDoubleLine(base, axes, color='black', zorder=5, x=0.5, y=0.5, center_x=0.0, center_y=0.0)

Bases: BaseInteractor

Draw 2 vertical lines moving in opposite direction and centered on a point (PointInteractor)

__annotations__ = {}
__doc__ = '\nDraw 2 vertical lines moving in opposite direction and centered on\na point (PointInteractor)\n'
__firstlineno__ = 410
__init__(base, axes, color='black', zorder=5, x=0.5, y=0.5, center_x=0.0, center_y=0.0)
__module__ = 'sas.qtgui.Plotting.Slicers.BoxSum'
__static_attributes__ = ('axes', 'center_x', 'center_y', 'color', 'half_height', 'half_width', 'has_move', 'layernum', 'left_line', 'markers', 'right_line', 'right_marker', 'save_half_height', 'save_half_width', 'save_x1', 'save_x2', 'save_y1', 'save_y2', 'x1', 'x2', 'y1', 'y2')
clear()

Clear this slicer and its markers

move(x, y, ev)

Process move to a new position, making sure that the move is allowed.

moveend(ev)

After a dragging motion reset the flag self.has_move to False

restore(ev)

Restore the roughness for this layer.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc.

setCursor(x, y)

Update the figure given x and y

setLayer(n)

Allow adding plot to the same panel :param n: the number of layer

update(x1=None, x2=None, y1=None, y2=None, width=None, height=None, center=None)

Draw the new roughness on the graph. :param x1: new maximum value of x coordinates :param x2: new minimum value of x coordinates :param y1: new maximum value of y coordinates :param y2: new minimum value of y coordinates :param width: is the width of the new rectangle :param height: is the height of the new rectangle :param center: provided x, y coordinates of the center point

sas.qtgui.Plotting.Slicers.MultiSlicerBase module

Base class for creating multiple symmetric slicers.

class sas.qtgui.Plotting.Slicers.MultiSlicerBase.MultiSlicerBase(base, axes, count, item=None, color='black', zorder=3)

Bases: BaseInteractor, SlicerModel, StackableMixin, ABC

Base class for creating multiple symmetric slicers that move together as a unit.

This class handles: - Creating multiple slicer instances evenly spaced around the circle - Synchronizing movement of all slicers with one master - Disabling interaction for non-master slicers - Managing model updates and UI parameter changes

Subclasses must implement: - _get_slicer_class() - return the single slicer class to instantiate - _get_interactor_names() - return list of interactor attribute names - _update_slicer_position(slicer, index, master) - update position for each slicer - _on_model_changed(item) - handle UI parameter changes

__abstractmethods__ = frozenset({'_get_interactor_names', '_get_slicer_class', '_update_slicer_position'})
__doc__ = '\nBase class for creating multiple symmetric slicers that move together as a unit.\n\nThis class handles:\n- Creating multiple slicer instances evenly spaced around the circle\n- Synchronizing movement of all slicers with one master\n- Disabling interaction for non-master slicers\n- Managing model updates and UI parameter changes\n\nSubclasses must implement:\n- _get_slicer_class() - return the single slicer class to instantiate\n- _get_interactor_names() - return list of interactor attribute names\n- _update_slicer_position(slicer, index, master) - update position for each slicer\n- _on_model_changed(item) - handle UI parameter changes\n'
__firstlineno__ = 21
__init__(base, axes, count, item=None, color='black', zorder=3)
__module__ = 'sas.qtgui.Plotting.Slicers.MultiSlicerBase'
__static_attributes__ = ('_item', '_model', 'angle_step', 'axes', 'base', 'connect', 'count', 'data', 'dqmin', 'markers', 'original_moveends', 'original_moves', 'qmax', 'slicers')
_abc_impl = <_abc._abc_data object>
_connect_master_slicer()

Connect the moveend signal of the first slicer to update all slicers.

_create_slicers(zorder)

Create all slicers and position them evenly around the circle.

Parameters: - zorder: The z-order for drawing the slicers

_disable_slicer_interaction(slicer)

Disable interaction for the given slicer to avoid clutter. The slicer lines remain visible for context but are not interactive.

Parameters: - slicer: The slicer to disable interaction for

abstractmethod _get_interactor_names()

Return the list of interactor attribute names. Must be implemented by subclasses.

abstractmethod _get_slicer_class()

Return the slicer class to instantiate. Must be implemented by subclasses.

_on_model_changed(item)

Base implementation with batching - subclasses should call this after processing

_synchronized_move(x, y, ev, interactor_name)

Called during dragging to update all slicers.

Parameters: - x: The x-coordinate - y: The y-coordinate - ev: The mouse event - interactor_name: The name of the interactor being moved

_synchronized_moveend(ev, interactor_name)

Called after dragging to finalize all slicers.

abstractmethod _update_slicer_position(slicer, index, master, moved_interactor_name=None)

Update the position of the given slicer based on the master slicer. Must be implemented by subclasses.

Parameters: - slicer: The slicer to update - index: The index of the slicer in the list - master: The master slicer to synchronize with - moved_interactor_name: The name of the interactor that was moved

clear()

Clear all slicers from the axes.

draw()

Draw the canvas.

getParams()

Get parameters from the master slicer.

setParams(params)

Set parameters for all slicers based on the master slicer.

Parameters: - params: Dictionary of parameters to set

validate(param_name, param_value)

Validate parameters using master slicer

class sas.qtgui.Plotting.Slicers.MultiSlicerBase.SectorInteractorMulti(base, axes, count, item=None, color='black', zorder=3)

Bases: MultiSlicerBase

Creates multiple symmetric sector slicers that move together as a unit.

__abstractmethods__ = frozenset({})
__doc__ = '\nCreates multiple symmetric sector slicers that move together as a unit.\n'
__firstlineno__ = 602
__module__ = 'sas.qtgui.Plotting.Slicers.MultiSlicerBase'
__static_attributes__ = ()
_abc_impl = <_abc._abc_data object>
_get_interactor_names()

Return list of interactor names for sector slicers

_get_slicer_class()

Return the SectorInteractor class

_on_model_changed(item)

Handle parameter changes from UI

_update_slicer_position(slicer, index, master, moved_interactor_name=None)

Update sector position with angular offset

class sas.qtgui.Plotting.Slicers.MultiSlicerBase.WedgeInteractorMulti(base, axes, count, slicer_class, item=None, color='black', zorder=3)

Bases: MultiSlicerBase

Creates multiple symmetric wedge slicers that move together as a unit. Works with both WedgeInteractorPhi (phi mode) and WedgeInteractorQ (Q mode). The plotting mode is determined by the slicer_class passed to __init__.

__abstractmethods__ = frozenset({})
__doc__ = '\nCreates multiple symmetric wedge slicers that move together as a unit.\nWorks with both WedgeInteractorPhi (phi mode) and WedgeInteractorQ (Q mode).\nThe plotting mode is determined by the slicer_class passed to __init__.\n'
__firstlineno__ = 427
__init__(base, axes, count, slicer_class, item=None, color='black', zorder=3)

Initialize multiple wedge slicers.

Parameters: - base: The base plotter - axes: The matplotlib axes - count: Number of slicers to create - slicer_class: Either WedgeInteractorPhi or WedgeInteractorQ - item: Optional data item - color: Color for the slicers - zorder: Z-order for drawing

__module__ = 'sas.qtgui.Plotting.Slicers.MultiSlicerBase'
__static_attributes__ = ('slicer_class',)
_abc_impl = <_abc._abc_data object>
_get_interactor_names()

Return list of interactor names for wedge slicers

_get_slicer_class()

Return the wedge slicer class (Phi or Q mode)

_on_model_changed(item)

Handle parameter changes from UI

_update_slicer_position(slicer, index, master, moved_interactor_name=None)

Update wedge position with angular offset

class sas.qtgui.Plotting.Slicers.MultiSlicerBase.WedgeInteractorPhiMulti(base, axes, count, item=None, color='black', zorder=3)

Bases: WedgeInteractorMulti

Multiple wedge slicers in Phi mode (plots vs phi)

__abstractmethods__ = frozenset({})
__doc__ = 'Multiple wedge slicers in Phi mode (plots vs phi)'
__firstlineno__ = 590
__init__(base, axes, count, item=None, color='black', zorder=3)

Initialize multiple wedge slicers.

Parameters: - base: The base plotter - axes: The matplotlib axes - count: Number of slicers to create - slicer_class: Either WedgeInteractorPhi or WedgeInteractorQ - item: Optional data item - color: Color for the slicers - zorder: Z-order for drawing

__module__ = 'sas.qtgui.Plotting.Slicers.MultiSlicerBase'
__static_attributes__ = ()
_abc_impl = <_abc._abc_data object>
class sas.qtgui.Plotting.Slicers.MultiSlicerBase.WedgeInteractorQMulti(base, axes, count, item=None, color='black', zorder=3)

Bases: WedgeInteractorMulti

Multiple wedge slicers in Q mode (plots vs Q)

__abstractmethods__ = frozenset({})
__doc__ = 'Multiple wedge slicers in Q mode (plots vs Q)'
__firstlineno__ = 596
__init__(base, axes, count, item=None, color='black', zorder=3)

Initialize multiple wedge slicers.

Parameters: - base: The base plotter - axes: The matplotlib axes - count: Number of slicers to create - slicer_class: Either WedgeInteractorPhi or WedgeInteractorQ - item: Optional data item - color: Color for the slicers - zorder: Z-order for drawing

__module__ = 'sas.qtgui.Plotting.Slicers.MultiSlicerBase'
__static_attributes__ = ()
_abc_impl = <_abc._abc_data object>

sas.qtgui.Plotting.Slicers.RadiusInteractor module

class sas.qtgui.Plotting.Slicers.RadiusInteractor.RadiusInteractor(base, axes, color='black', zorder=5, r1=1.0, r2=2.0, theta=1.0471975511965976, phi=0.39269908169872414)

Bases: BaseInteractor

Draw a pair of lines radiating from a center at [0,0], between radius values r1 and r2 with and average angle from the x-axis of theta, and an angular diaplacement of phi either side of this average. Used for example to to define the left and right edges of the a wedge area on a plot, see WedgeInteractor. User interaction adjusts the parameter phi.

Parameters:
  • r1 – radius of the inner end of the radial lines

  • r2 – radius of the outer end of the radial lines

  • theta – average angle of the lines from the x-axis

  • phi – angular displacement of the lines either side of theta

__annotations__ = {}
__doc__ = '\nDraw a pair of lines radiating from a center at [0,0], between radius\nvalues r1 and r2 with and average angle from the x-axis of theta, and an\nangular diaplacement of phi either side of this average. Used for example\nto to define the left and right edges of the a wedge area on a plot, see\nWedgeInteractor. User interaction adjusts the parameter phi.\n\n:param r1: radius of the inner end of the radial lines\n:param r2: radius of the outer end of the radial lines\n:param theta: average angle of the lines from the x-axis\n:param phi: angular displacement of the lines either side of theta\n'
__firstlineno__ = 6
__init__(base, axes, color='black', zorder=5, r1=1.0, r2=2.0, theta=1.0471975511965976, phi=0.39269908169872414)
__module__ = 'sas.qtgui.Plotting.Slicers.RadiusInteractor'
__static_attributes__ = ('axes', 'color', 'has_move', 'l_line', 'l_marker', 'layernum', 'markers', 'phi', 'r1', 'r2', 'r_line', 'r_marker', 'save_phi', 'theta')
clear()

Clear this slicer and its markers

move(x, y, ev)

Process move to a new position.

moveend(ev)

Called when any dragging motion ends. Redraw the plot with new parameters and set self.has_move to False.

restore(ev)

Restore the roughness for this layer.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc.

set_cursor(x, y)
set_layer(n)

Allow adding plot to the same panel :param n: the number of layer

update(r1=None, r2=None, theta=None, phi=None)

Draw the new roughness on the graph. :param r1: radius of the inner end of the radial lines :param r2: radius of the outer end of the radial lines :param theta: average angle of the lines from the x-axis :param phi: angular displacement of the lines either side of theta

sas.qtgui.Plotting.Slicers.SectorSlicer module

class sas.qtgui.Plotting.Slicers.SectorSlicer.LineInteractor(base, axes, color='black', zorder=5, r=1.0, theta=0.7853981633974483, half_length=False)

Bases: BaseInteractor

Draws a line though 0,0 on a data2D plot. This is used to define the centerline around with other lines can be drawn to define a region of interest (such as a sector).

Parameters:
  • theta – the angle between the middle line and x- axis

  • half_length – Defaults to False. If True, the line is drawn from the origin rather than across the whole graph.

__annotations__ = {}
__doc__ = '\nDraws a line though 0,0 on a data2D plot. This is used to define the\ncenterline around with other lines can be drawn to define a region of\ninterest (such as a sector).\n\n:param theta: the angle between the middle line and x- axis\n:param half_length: Defaults to False. If True, the line is drawn from the\n                    origin rather than across the whole graph.\n'
__firstlineno__ = 492
__init__(base, axes, color='black', zorder=5, r=1.0, theta=0.7853981633974483, half_length=False)
__module__ = 'sas.qtgui.Plotting.Slicers.SectorSlicer'
__static_attributes__ = ('axes', 'color', 'half_length', 'has_move', 'inner_marker', 'layernum', 'line', 'markers', 'radius', 'save_theta', 'scale', 'theta')
clear()
getParams()
move(x, y, ev)

Process move to a new position, making sure that the move is allowed.

moveend(ev)
restore(ev)

Restore the roughness for this layer.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc.

setParams(params)
set_cursor(x, y)
set_layer(n)
update(theta=None)

Draw the new roughness on the graph.

class sas.qtgui.Plotting.Slicers.SectorSlicer.SectorInteractor(base, axes, item=None, color='black', zorder=3)

Bases: BaseInteractor, SlicerModel, StackableMixin

SectorInteractor plots a data1D average of a sector area defined in a Data2D object. The data1D averaging itself is performed in sasdata by manipulations.py. Sectors all go through a single point as (0,0).

This class uses two other classes, LineInteractor and SideInteractor, to define a sector centered around a main line defined by LineInteractor which goes through 0,0 at some user settable angle theta from 0. The sector itself is defined by the right and left sidelines, both of which also go through (0,0), and set by SideInteractor from -phi to +phi around the center line defined by the main line. All points at a constant Q from -phi to +phi are averaged together to provide a 1D array in Q (to be plotted as a function of Q).

..TODO: the 2 subclasses here are the same as used by the BoxSum. These

should probably be abstracted out.

__annotations__ = {'fold': 'bool'}
__doc__ = '\nSectorInteractor plots a data1D average of a sector area defined in a\nData2D object. The data1D averaging itself is performed in sasdata by\nmanipulations.py. Sectors all go through a single point as (0,0).\n\nThis class uses two other classes, LineInteractor and SideInteractor, to\ndefine a sector centered around a main line defined by LineInteractor\nwhich goes through 0,0 at some user settable angle theta from 0. The\nsector itself is defined by the right and left sidelines, both of which\nalso go through (0,0), and set by SideInteractor from -phi to +phi around\nthe center line defined by the main line. All points at a constant Q from\n-phi to +phi are averaged together to provide a 1D array in Q (to be\nplotted as a function of Q).\n\n    ..TODO: the 2 subclasses here are the same as used by the BoxSum. These\n        should probably be abstracted out.\n'
__firstlineno__ = 15
__init__(base, axes, item=None, color='black', zorder=3)
__module__ = 'sas.qtgui.Plotting.Slicers.SectorSlicer'
__static_attributes__ = ('_item', '_plot_id', 'axes', 'connect', 'fold', 'layernum', 'left_line', 'main_line', 'markers', 'nbins', 'phi', 'qmax', 'right_line', 'theta2')
_get_slicer_type_id()

Return the slicer type identifier

_post_data(nbins=None)

compute sector averaging of data2D into data1D :param nbins: the number of point to plot for the average 1D data

clear()

Clear this slicer and its markers

draw()

Redraw canvas

fold: bool
getParams()

Store a copy of values of parameters of the slicer into a dictionary. :return params: the dictionary created

move(x, y, ev)

Process move to a new position, making sure that the move is allowed.

moveend(ev)

Called a dragging motion ends.Get slicer event

restore(ev)

Restore the roughness for this layer.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc.

setParams(params)

Receive a dictionary and reset the slicer with values contained in the values of the dictionary.

Parameters:

params – a dictionary containing name of slicer parameters and values the user assigned to the slicer.

set_cursor(x, y)
set_layer(n)

Allow adding plot to the same panel

Parameters:

n – the number of layer

update()

Respond to changes in the model by recalculating the profiles and resetting the widgets.

validate(param_name, param_value)

Test the proposed new value “value” for row “row” of parameters

class sas.qtgui.Plotting.Slicers.SectorSlicer.SideInteractor(base, axes, color='black', zorder=5, r=1.0, phi=0.7853981633974483, theta2=1.0471975511965976)

Bases: BaseInteractor

Draws a line though 0,0 on a data2D plot with reference to a center line. This is used to define both a left and right line which are always updated together as they must remain symmetric at some phi value around the main line (at -phi and +phi).

Parameters:
  • phi – the phase between the middle line and one side line

  • theta2 – the angle between the middle line and x- axis

__annotations__ = {}
__doc__ = '\nDraws a line though 0,0 on a data2D plot with reference to a center line.\nThis is used to define both a left and right line which are always updated\ntogether as they must remain symmetric at some phi value around the main\nline (at -phi and +phi).\n\n:param phi: the phase between the middle line and one side line\n:param theta2: the angle between the middle line and x- axis\n\n'
__firstlineno__ = 297
__init__(base, axes, color='black', zorder=5, r=1.0, phi=0.7853981633974483, theta2=1.0471975511965976)
__module__ = 'sas.qtgui.Plotting.Slicers.SectorSlicer'
__static_attributes__ = ('axes', 'color', 'has_move', 'inner_marker', 'layernum', 'left_moving', 'line', 'markers', 'phi', 'radius', 'save_theta', 'theta', 'theta2')
clear()

Clear the slicer and all connected events related to this slicer

getParams()
move(x, y, ev)

Process move to a new position, making sure that the move is allowed.

moveend(ev)
restore(ev)

Restore the roughness for this layer.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc.

setParams(params)
set_cursor(x, y)
set_layer(n)

Allow adding plot to the same panel

Parameters:

n – the number of layer

update(phi=None, delta=None, mline=None, side=False, left=False, right=False)

Draw oblique line

Parameters:
  • phi – the phase between the middle line and the current line

  • delta – phi/2 applied only when the mline was moved

sas.qtgui.Plotting.Slicers.SlicerUtils module

Utility functions for slicers in the 2D plotter, including unique ID generation and stacking mixin.

class sas.qtgui.Plotting.Slicers.SlicerUtils.StackableMixin

Bases: object

Mixin class that provides stacking functionality for slicer plots. Any slicer that inherits from this mixin can stack multiple plots on the same window.

__annotations__ = {}
__dict__ = mappingproxy({'__module__': 'sas.qtgui.Plotting.Slicers.SlicerUtils', '__firstlineno__': 53, '__doc__': '\nMixin class that provides stacking functionality for slicer plots.\nAny slicer that inherits from this mixin can stack multiple plots on the same window.\n', '__init__': <function StackableMixin.__init__>, 'as_list': <staticmethod(<function StackableMixin.as_list>)>, '_get_slicer_type_id': <function StackableMixin._get_slicer_type_id>, '_create_or_update_plot': <function StackableMixin._create_or_update_plot>, '_find_stackable_plot_window': <function StackableMixin._find_stackable_plot_window>, '_emit_plot_update': <function StackableMixin._emit_plot_update>, '_append_to_plot_window': <function StackableMixin._append_to_plot_window>, '_create_new_plot': <function StackableMixin._create_new_plot>, '_update_existing_plot': <function StackableMixin._update_existing_plot>, '__static_attributes__': ('_actual_plot_id', '_plot_window'), '__dict__': <attribute '__dict__' of 'StackableMixin' objects>, '__weakref__': <attribute '__weakref__' of 'StackableMixin' objects>, '__annotations__': {}})
__doc__ = '\nMixin class that provides stacking functionality for slicer plots.\nAny slicer that inherits from this mixin can stack multiple plots on the same window.\n'
__firstlineno__ = 53
__init__()

Initialize stacking-related attributes

__module__ = 'sas.qtgui.Plotting.Slicers.SlicerUtils'
__static_attributes__ = ('_actual_plot_id', '_plot_window')
__weakref__

list of weak references to the object

_append_to_plot_window(plot_window: object, new_plot: Data1D, item) str

Append new data to an existing plot window.

Parameters:
  • plot_window – The existing plot window to append to

  • new_plot – The new Data1D object to add

  • item – The item for the data model

Returns:

The actual ID assigned to the plot

_create_new_plot(new_plot: Data1D, item) None

Create a new plot window.

Parameters:
  • new_plot – The Data1D object to plot

  • item – The data explorer item

_create_or_update_plot(new_plot: Data1D, item) None

Create a new plot or update/stack onto an existing one based on state.

Parameters:
  • new_plot – The Data1D object to plot

  • item – The data explorer item

_emit_plot_update(plots)

Emit plot update signals, with batching support. When self.base.manager._suspend_plot_signals is True, buffer updates to self.base.manager._pending_plot_updates instead of emitting immediately.

_find_stackable_plot_window() object

Find an existing plot window that can accept this slicer’s data. Returns the latest matching plot window if found, None otherwise.

Returns:

Plot window if found, None otherwise

_get_slicer_type_id() str

Get the type identifier for this slicer. Should be overridden by subclasses to return something like “AnnulusPhi” + data.name

Returns:

String identifying the slicer type and source data

_update_existing_plot(new_plot, item)

Update data in existing plot window.

Parameters:
  • new_plot – The updated Data1D object

  • item – The data explorer item

static as_list(data: object) list

Ensure data is returned as a list. Returns an empty list if data is None, a single-item list if data is a single item

Parameters:

data – Data which may be None, a single item, or a list

Returns:

List of data items

sas.qtgui.Plotting.Slicers.SlicerUtils._count_matching_ids(item, base_id: str) int

Recursively count items with IDs starting with base_id.

Parameters:
  • item – Tree item to search

  • base_id – The base identifier to match

Returns:

Count of matching items in this subtree

sas.qtgui.Plotting.Slicers.SlicerUtils.generate_unique_plot_id(base_id: str, item) str

Generate a unique plot ID by checking existing plots in the data tree.

Parameters:
  • base_id – The base identifier string (e.g., “SectorQ” + data.name)

  • item – The current item in the data explorer tree

Returns:

A unique ID string, either base_id or base_id_N where N is a number

sas.qtgui.Plotting.Slicers.WedgeSlicer module

class sas.qtgui.Plotting.Slicers.WedgeSlicer.WedgeInteractor(base, axes, item=None, color='black', zorder=3)

Bases: BaseInteractor, SlicerModel, StackableMixin

This WedgeInteractor is a cross between the SectorInteractor and the AnnulusInteractor. It plots a data1D average of a wedge area defined in a Data2D object, in either the Q direction or the Phi direction. The data1D averaging itself is performed in sasdata by manipulations.py.

This class uses three other classes, ArcInteractor (in ArcInteractor.py), RadiusInteractor (in RadiusInteractor.py), and LineInteractor (in SectorSlicer.py), to define a wedge area contained between two radial lines running through (0,0) defining the left and right edges of the wedge (similar to the sector), and two rings at Q1 and Q2 (similar to the annulus). The wedge is centred on the line defined by LineInteractor, which the radial lines move symmetrically around. This class is itself subclassed by SectorInteractorPhi and SectorInteractorQ which define the direction of the averaging. SectorInteractorPhi averages all Q points at constant Phi (as for the AnnulusSlicer) and SectorInteractorQ averages all phi points at constant Q (as for the SectorSlicer).

__annotations__ = {}
__doc__ = '\nThis WedgeInteractor is a cross between the SectorInteractor and the\nAnnulusInteractor. It plots a data1D average of a wedge area defined in a\nData2D object, in either the Q direction or the Phi direction. The data1D\naveraging itself is performed in sasdata by manipulations.py.\n\nThis class uses three other classes, ArcInteractor (in ArcInteractor.py),\nRadiusInteractor (in RadiusInteractor.py), and LineInteractor\n(in SectorSlicer.py), to define a wedge area contained\nbetween two radial lines running through (0,0) defining the left and right\nedges of the wedge (similar to the sector), and two rings at Q1 and Q2\n(similar to the annulus). The wedge is centred on the line defined by\nLineInteractor, which the radial lines move symmetrically around.\nThis class is itself subclassed by SectorInteractorPhi and\nSectorInteractorQ which define the direction of the averaging.\nSectorInteractorPhi averages all Q points at constant Phi (as for the\nAnnulusSlicer) and SectorInteractorQ averages all phi points at constant Q\n(as for the SectorSlicer).\n'
__firstlineno__ = 22
__init__(base, axes, item=None, color='black', zorder=3)
__module__ = 'sas.qtgui.Plotting.Slicers.WedgeSlicer'
__static_attributes__ = ('_item', '_plot_id', 'averager', 'axes', 'central_line', 'connect', 'dqmin', 'fold', 'inner_arc', 'layernum', 'markers', 'nbins', 'outer_arc', 'phi', 'qmax', 'r1', 'r2', 'radial_lines', 'theta')
_get_slicer_type_id()

Return the slicer type identifier

_post_data(new_sector=None, nbins=None)

post 1D data averaging in Q or Phi given new_sector type

Parameters:
  • new_sector – slicer used for directional averaging in Q or Phi

  • nbins – the number of point plotted when averaging

:TODO

Unlike other slicers, the two sector types are sufficiently different that this method contains three instances of If (check class name) do x. The point of post_data vs _post_data I think was to avoid this kind of thing and suggests that in this case we may need a new method in the WedgeInteracgtorPhi and WedgeInteractorQ to handle these specifics. Probably by creating the 1D plot object in those top level classes along with the specifc attributes.

clear()

Clear the slicer and all connected events related to this slicer

draw()

Draws the Canvas using the canvas.draw from the calling class that instantiated this object.

getParams()

Store a copy of values of parameters of the slicer into a dictionary. :return params: the dictionary created

move(x, y, ev)

Process move to a new position.

moveend(ev)

Called after a dragging event. Post the slicer new parameters and creates a new Data1D corresponding to the new average

restore(ev)

Restore the roughness for this layer.

save(ev)

Remember the roughness for this layer and the next so that we can restore on Esc.

setParams(params)

Receive a dictionary and reset the slicer with values contained in the values of the dictionary.

Parameters:

params – a dictionary containing name of slicer parameters and values the user assigned to the slicer.

set_cursor(x, y)
set_layer(n)

Allow adding plot to the same panel :param n: the number of layer

update()

If one of the interactors has been moved, update it and the parameter it controls, then update the other interactors accordingly

validate(param_name, param_value)

Validate input from user. Values get checked at apply time.

class sas.qtgui.Plotting.Slicers.WedgeSlicer.WedgeInteractorPhi(base, axes, item=None, color='black', zorder=3)

Bases: WedgeInteractor

Average in phi direction. The data for all Q at a constant phi are averaged together to provide a 1D array in phi (to be plotted as a function of phi)

__annotations__ = {}
__doc__ = '\nAverage in phi direction. The data for all Q at a constant phi are\naveraged together to provide a 1D array in phi (to be plotted as a function\nof phi)\n'
__firstlineno__ = 383
__init__(base, axes, item=None, color='black', zorder=3)
__module__ = 'sas.qtgui.Plotting.Slicers.WedgeSlicer'
__static_attributes__ = ('base',)
_post_data(new_sector=None, nbins=None)

post 1D data averaging in Q or Phi given new_sector type

Parameters:
  • new_sector – slicer used for directional averaging in Q or Phi

  • nbins – the number of point plotted when averaging

:TODO

Unlike other slicers, the two sector types are sufficiently different that this method contains three instances of If (check class name) do x. The point of post_data vs _post_data I think was to avoid this kind of thing and suggests that in this case we may need a new method in the WedgeInteracgtorPhi and WedgeInteractorQ to handle these specifics. Probably by creating the 1D plot object in those top level classes along with the specifc attributes.

class sas.qtgui.Plotting.Slicers.WedgeSlicer.WedgeInteractorPhiMulti(base, axes, count, item=None, color='black', zorder=3)

Bases: BaseInteractor, SlicerModel, StackableMixin

Creates multiple symmetric wedge slicers that move together as a unit.

__annotations__ = {}
__doc__ = '\nCreates multiple symmetric wedge slicers that move together as a unit.\n'
__firstlineno__ = 401
__init__(base, axes, count, item=None, color='black', zorder=3)
__module__ = 'sas.qtgui.Plotting.Slicers.WedgeSlicer'
__static_attributes__ = ('_item', '_model', 'angle_step', 'axes', 'base', 'connect', 'count', 'data', 'dqmin', 'markers', 'original_moveends', 'qmax', 'wedges')
_connect_master_wedge()

Connect the moveend signal of the first wedge to update all wedges.

_create_slicers(zorder)

Create all wedge interactors and position them evenly around the circle.

_on_moveend(ev)

Called after a dragging event. Update all wedges to the new position.

_remove_wedge_markers(wedge)

Remove markers from non-master wedges to avoid clutter. The wedge lines remain visible for context but are not interactive.

_synchronized_moveend(ev, interactor_name)

Call the original moveend method and then update all wedges.

update()

Update all wedge interactors to move together. Called during interactive dragging.

class sas.qtgui.Plotting.Slicers.WedgeSlicer.WedgeInteractorQ(base, axes, item=None, color='black', zorder=3)

Bases: WedgeInteractor

Average in Q direction. The data for all phi at a constant Q are averaged together to provide a 1D array in Q (to be plotted as a function of Q)

__annotations__ = {}
__doc__ = '\nAverage in Q direction. The data for all phi at a constant Q are\naveraged together to provide a 1D array in Q (to be plotted as a function\nof Q)\n'
__firstlineno__ = 365
__init__(base, axes, item=None, color='black', zorder=3)
__module__ = 'sas.qtgui.Plotting.Slicers.WedgeSlicer'
__static_attributes__ = ('base',)
_post_data(new_sector=None, nbins=None)

post 1D data averaging in Q or Phi given new_sector type

Parameters:
  • new_sector – slicer used for directional averaging in Q or Phi

  • nbins – the number of point plotted when averaging

:TODO

Unlike other slicers, the two sector types are sufficiently different that this method contains three instances of If (check class name) do x. The point of post_data vs _post_data I think was to avoid this kind of thing and suggests that in this case we may need a new method in the WedgeInteracgtorPhi and WedgeInteractorQ to handle these specifics. Probably by creating the 1D plot object in those top level classes along with the specifc attributes.

sas.qtgui.Plotting.Slicers.WedgeSlicer._normalize_phi_for_wedge_display(phi_deg, delta_phi_deg)

Normalize phi to match wedge display convention across +/-180 boundary.

Module contents