Shapes
Defines the shapes which are used with a ceed.function to create regions
with time-varying intensity during an experiment ceed.stage.
PaintCanvasBehavior provides the widget
functionality such that when a user draws on the screen,
PaintShape instances are created and added to
it.
CeedPaintCanvasBehavior provides a more specialized painter canvas.
Specifically, in addition to being able to draw shapes, it adds the ability
to organize shapes into CeedPaintCanvasBehavior.groups.
Shape plugin
Although Ceed does not offer a plugin for shapes, it’s simple to create shapes and shape groups with a script, dump it to disk as a yaml file, and import it into Ceed from the GUI.
Following is an example using CeedPaintCanvasBehavior and the methods
of its baseclass PaintCanvasBehavior as well
as using the Ceed-inherited versions of the shapes;
CeedPaintCircle (PaintCircle),
CeedPaintEllipse (PaintEllipse),
CeedPaintPolygon (PaintPolygon).
Each shape class has a class method create_shape that can be used to create
the shape, because you should not instantiate the shape class manually because
the resulting shapes may not be valid:
from ceed.shape import CeedPaintCanvasBehavior, CeedPaintCircle,         CeedPaintEllipse, CeedPaintPolygon
from ceed.storage.controller import CeedDataWriterBase
# create shape factory to which we'll add shapes
shape_factory = CeedPaintCanvasBehavior()
# create the shapes and name them. We use the Shape classes from Ceed
ellipse = CeedPaintEllipse.create_shape(
    center=(250, 450), radius_x=200, radius_y=400, name='ellipse')
circle = CeedPaintCircle.create_shape(
    center=(700, 300), radius=200, name='circle')
polygon = CeedPaintPolygon.create_shape(
    points=[275, 300, 700, 300, 500, 800], name='polygon')
# add the shapes to factory
shape_factory.add_shape(ellipse)
shape_factory.add_shape(circle)
shape_factory.add_shape(polygon)
# create group, name it, and add shapes to it
group = shape_factory.add_group()
group.name = 'shapes'
group.add_shape(ellipse)
group.add_shape(polygon)
# save it to disk for import later
CeedDataWriterBase.save_config_to_yaml(
    filename, shape_factory=shape_factory)
You can also create the shapes by type name using
create_shape():
from ceed.shape import CeedPaintCanvasBehavior
from ceed.storage.controller import CeedDataWriterBase
# create shape factory to which we'll add shapes
shape_factory = CeedPaintCanvasBehavior()
# create shape using config, including name
ellipse = shape_factory.create_shape(
    'ellipse', center=(250, 450), radius_x=200, radius_y=400,
    name='ellipse')
circle = shape_factory.create_shape(
    'circle', center=(700, 300), radius=200, name='circle')
polygon = shape_factory.create_shape(
    'polygon', points=[275, 300, 700, 300, 500, 800], name='polygon')
# add the shapes to factory
shape_factory.add_shape(ellipse)
shape_factory.add_shape(circle)
shape_factory.add_shape(polygon)
# create group, name it, and add shapes to it
group = shape_factory.add_group()
group.name = 'shapes'
group.add_shape(ellipse)
group.add_shape(polygon)
# save it to disk for import later
CeedDataWriterBase.save_config_to_yaml(
    filename, shape_factory=shape_factory)
See save_config_to_yaml()
for a full example with functions/stages.
If you need to create many shapes or groups and importing them in the Ceed GUI
is slow, consider setting its no_display or
no_display to True. E.g.
CeedPaintEllipse.create_shape(..., no_display=True).
The ProPixx projector used by Ceed has a resolution of 1920x108, so that should
be the maximum extent of the shapes. The exact available drawing area can also
be read/set in the config at
screen_width and
screen_height.
- class ceed.shape.CeedPaintCanvasBehavior(**kwargs)
 Bases:
kivy_garden.painter.PaintCanvasBehaviorController base class for drawing and managing the shapes.
A shape is drawn by the user in the GUI and automatically added by
kivy_garden.painter.PaintCanvasBehaviorto itskivy_garden.painter.PaintCanvasBehavior.shapeslist. This class manages all that without any of the associated GUI components that is shown to the user (e.g. the ability name shapes etc.). The GUI components is added by theCeedPainter.So when run from the GUI, an instance of
ceed.shape.shape_widgets.CeedPainteris the class used to manage the shapes. When running during analysis, and instance of this class is used instead as no visualizations is required..In addition to the
kivy_garden.painter.PaintCanvasBehavior.shapes, the class addsgroupsfor grouping shapes; aCeedShapeGroupsimply groups a collection ofCeedShapeby their name.- Events
 - on_remove_shape:
 Triggered when a
CeedShapeis removed. The first parameter is the shape removed.- on_remove_group:
 Triggered when a
CeedShapeGroupis removed. The first parameter is the group removed.- on_changed:
 Triggered whenever a
CeedShapeorCeedShapeGroupis added or removed, or if a configuration option of the objects is changed.
- groups: List[ceed.shape.CeedShapeGroup]
 List of
CeedShapeGroupinstances created in Ceed.
- shape_names: Dict[str, ceed.shape.CeedShape]
 The name ->
CeedShapedict. The key is the shape’s name and the corresponding value is theCeedShapeinstance.
- shape_group_names: Dict[str, ceed.shape.CeedShapeGroup]
 The name ->
CeedShapeGroupdict. The key is the group’s name and the corresponding value is theCeedShapeGroupinstance.
- unique_names: ceed.utils.UniqueNames = None
 A set that tracks existing shape/group names to help us ensure all shapes/groups have unique names.
- add_shape(shape: ceed.shape.CeedShape)
 Add the shape to
shapesand to the painter.- Parameters
 shape –
PaintShapeinstance to add.- Returns
 A bool indicating whether the shape was successfully added.
- remove_shape(shape: ceed.shape.CeedShape)
 Removes the shape from the painter and from
shapes.- Parameters
 shape –
PaintShapeinstance to remove.- Returns
 A bool indicating whether the shape was successfully removed.
- reorder_shape(shape: ceed.shape.CeedShape, before_shape: Optional[ceed.shape.CeedShape] = None)
 Move the shape up or down in depth, in terms of the shape order in
shapesand in the canvas.This effect whether a shape will obscure another.
- Parameters
 shape –
PaintShapeinstance to move from it’s current position.before_shape – Where to add it. If None, it is moved at the end, otherwise it is moved after the given
PaintShapeinshapes.
- move_shape_lower(shape: ceed.shape.CeedShape)
 Moves the shape one shape down. I.e. if there are two shapes and this shape is at index 1, it gets moved to index 0.
This changes the depth ordering of the shapes.
- Parameters
 shape – The
CeedShapeinstance to move. It must exist inshapes.
- move_shape_upwards(shape: ceed.shape.CeedShape)
 Moves the shape one shape up. I.e. if there are two shapes and this shape is at index 0, it gets moved to index 1.
This changes the depth ordering of the shapes.
- Parameters
 shape – The
CeedShapeinstance to move. It must exist inshapes.
- add_group(group: Optional[ceed.shape.CeedShapeGroup] = None)
 Similar to
add_shape()but for aCeedShapeGroup.- Params
 - group: 
CeedShapeGroup The group to add. If None, the default, a new
CeedShapeGroupis created and added.
- group: 
 - Returns
 The
CeedShapeGroupadded.
- remove_group(group: ceed.shape.CeedShapeGroup)
 Similar to
remove_shape()but for aCeedShapeGroup.- Params
 - group: 
CeedShapeGroup The group to remove.
- group: 
 - Returns
 True if the group was removed, False otherwise.
- remove_all_groups()
 Removes all the
CeedShapeGroupinstances ingroups.
- add_selected_shapes_to_group(group: Optional[ceed.shape.CeedShapeGroup] = None)
 Adds all the
kivy_garden.painter.PaintCanvasBehavior.selected_shapesto thegroup.- Params
 - group: 
CeedShapeGroup The group to which to add the shapes. If None, the default, a new
CeedShapeGroupis created.
- group: 
 - Returns
 The
CeedShapeGrouppassed in or created.
- remove_shape_from_groups(shape: ceed.shape.CeedShape)
 Removes the
CeedShapefrom all the groups.- Params
 - shape: 
CeedShape The shape to remove.
- shape: 
 
- get_state(use_cache=False) dict
 Returns a dictionary containing all the configuration data for all the shapes and groups. It is used with
set_state()to later restore the state.- Parameters
 use_cache – If True, it’ll get the state using the cache from previous times the state was read and cached, if the cache exists.
- create_shape_from_state(state: dict, old_name_map: Dict[str, ceed.shape.CeedShape])
 Overrides
kivy_garden.painter.PaintCanvasBehavior.create_shape_from_state()and changes its signature.It takes an additional parameter,
old_name_map. When a shape is created from the givenstate, the shape’s new name could have been changed automatically so that it remained unique.old_name_mapis a dict that is filled in so the key is the old name (if present instate) and the associated value is the actual final shape name.
- set_state(state: dict, old_name_map: Dict[str, Union[ceed.shape.CeedShape, ceed.shape.CeedShapeGroup]])
 Takes the dict returned by
get_state()and adds the shapes and groups created form them.old_name_mapis the same as increate_shape_from_state().
- class ceed.shape.CeedShape(paint_widget_size=(0, 0), **kwargs)
 Bases:
objectA co-base class used with
kivy_garden.painter.PaintShapederived classes to add Ceed specific functionality to thekivy_garden.painter.PaintShapeclasses.- name: str
 A unique name associated with the shape.
- no_display: bool
 If set to True, the shape will not be displayed in the GUI, but it will still work like normal shapes during an experiment if it’s in a stage.
Not displaying the shape can make the stage/function/shape config load faster when importing from e.g. a yaml file because we don’t have to display it in the GUI. However, the shapes won’t be able to be added to a stage through the GUI, so you’d need to add it to the stage in the same script that generates the shapes. Or, add them to groups and leave the groups visible so it can be dragged to the stage.
- widget = None
 The
WidgetShapeused by ceed to customize the shape in the GUI.
- paint_widget_size = (0, 0)
 The size of the area used to draw the shapes. A shape is not allowed to have coordinates outside this area.
- get_cached_state(use_cache=False) Dict
 Like
get_state(), but it caches the result. And next time it is called, ifuse_cacheis True, the cached value will be returned, unless the config changed in between. Helpful for backup so we don’t recompute the full state.- Parameters
 use_cache – If True, it’ll get the state using the cache from previous times the state was read and cached, if the cache exists.
- Returns
 The state dict.
- get_state() dict
 Returns a dict representing the shape.
- property bounding_box
 Returns the
(x1, y1, x2, y2)describing the lower left and upper right points that define a bounding box for the shape.
- property centroid
 Returns the estimated
(x, y)centroid of the shape.
- property area
 Returns the estimated area of the shape.
- set_area(area)
 Sets the internal area of the shape in pixels. We try to get close to the requested area, but it is not likely to be exact.
- Parameters
 area – The area to be set.
- property collider
 Returns the collider instance from
kivy_garden.colliderused to manipulate and measure the shapes.
- class ceed.shape.CeedShapeGroup(**kwargs)
 Bases:
kivy._event.EventDispatcherHolds a collection of
CeedShapeinstances.It is helpful to group them when the same
ceed.functionis to be applied to multiple shapes.- Events
 - on_changed:
 Triggered whenever a child
CeedShapeis added or removed, or if a configuration option of the objects is changed.
- paint_widget
 The same as
kivy_garden.painter.PaintShape.paint_widget.
- name: str
 The unique name of the group. Similar to
CeedShape.name.
- no_display: bool
 Same as
CeedShape.no_display, but for this group.
- shapes: List[ceed.shape.CeedShape]
 A list that contains the
CeedShapeinstances that are part of this group.
- widget = None
 The
WidgetShapeGroupused by ceed to customize the group in the GUI.
- get_cached_state(use_cache=False) Dict
 Like
get_state(), but it caches the result. And next time it is called, ifuse_cacheis True, the cached value will be returned, unless the config changed in between. Helpful for backup so we don’t recompute the full state.- Parameters
 use_cache – If True, it’ll get the state using the cache from previous times the state was read and cached, if the cache exists.
use_cache – If True, it’ll get the state using the cache from previous times the state was read and cached, if the cache exists.
- Returns
 The state dict.
- get_state() dict
 Returns a dict representing the shape group.
- add_shape(shape: ceed.shape.CeedShape)
 Adds the shape to the group if it is not already in the group.
- remove_shape(shape: ceed.shape.CeedShape)
 Removes the shape from the group (and its
CeedShape.widget) if it is present.
- remove_all()
 Removes all the shapes from the group.
- class ceed.shape.CeedPaintCircle(paint_widget_size=(0, 0), **kwargs)
 Bases:
ceed.shape.CeedShape,kivy_garden.painter.PaintCircleA circle shape.
- class ceed.shape.CeedPaintEllipse(paint_widget_size=(0, 0), **kwargs)
 Bases:
ceed.shape.CeedShape,kivy_garden.painter.PaintEllipseAn ellipse shape.
- class ceed.shape.CeedPaintPolygon(paint_widget_size=(0, 0), **kwargs)
 Bases:
ceed.shape.CeedShape,kivy_garden.painter.PaintPolygonA polygonal shape.
- class ceed.shape.CeedPaintFreeformPolygon(paint_widget_size=(0, 0), **kwargs)
 Bases:
ceed.shape.CeedShape,kivy_garden.painter.PaintFreeformPolygonA polygonal shape drawn using freeform points.