Skip to content
Snippets Groups Projects
Commit e1a6bfb4 authored by Oscar Gustafsson's avatar Oscar Gustafsson :bicyclist:
Browse files

Enable configuration of aspects ratios in scheduler GUI

parent b2625bbe
No related branches found
No related tags found
1 merge request!145Enable configuration of aspects ratios in scheduler GUI
Pipeline #88643 passed
......@@ -460,7 +460,11 @@ class Schedule:
)
return ret
def _get_y_position(self, graph_id):
def _get_y_position(
self, graph_id, operation_height=1.0, operation_gap=None
):
if operation_gap is None:
operation_gap = OPERATION_GAP
y_location = self._y_locations[graph_id]
if y_location == None:
# Assign the lowest row number not yet in use
......@@ -470,9 +474,9 @@ class Schedule:
possible = set(range(len(self._start_times))) - used
y_location = min(possible)
self._y_locations[graph_id] = y_location
return OPERATION_GAP + y_location * (1 + OPERATION_GAP)
return operation_gap + y_location * (operation_height + operation_gap)
def _plot_schedule(self, ax):
def _plot_schedule(self, ax, operation_gap=None):
line_cache = []
def _draw_arrow(start, end, name="", laps=0):
......@@ -570,7 +574,7 @@ class Schedule:
ax.set_axisbelow(True)
ax.grid()
for graph_id, op_start_time in self._start_times.items():
ypos = -self._get_y_position(graph_id)
ypos = -self._get_y_position(graph_id, operation_gap=operation_gap)
op = self._sfg.find_by_id(graph_id)
# Rewrite to make better use of NumPy
latency_coords, execution_time_coords = op.get_plot_coordinates()
......@@ -596,13 +600,17 @@ class Schedule:
for graph_id, op_start_time in self._start_times.items():
op = self._sfg.find_by_id(graph_id)
_, out_coords = op.get_io_coordinates()
source_ypos = -self._get_y_position(graph_id)
source_ypos = -self._get_y_position(
graph_id, operation_gap=operation_gap
)
for output_port in op.outputs:
for output_signal in output_port.signals:
dest_op = output_signal.destination.operation
dest_start_time = self._start_times[dest_op.graph_id]
dest_ypos = -self._get_y_position(dest_op.graph_id)
dest_ypos = -self._get_y_position(
dest_op.graph_id, operation_gap=operation_gap
)
(
dest_in_coords,
_,
......@@ -623,7 +631,9 @@ class Schedule:
# Get operation with maximum position
max_pos_graph_id = max(self._y_locations, key=self._y_locations.get)
yposmin = -self._get_y_position(max_pos_graph_id) - OPERATION_GAP
yposmin = -self._get_y_position(
max_pos_graph_id, operation_gap=operation_gap
) - (OPERATION_GAP if operation_gap is None else operation_gap)
ax.axis([-1, self._schedule_time + 1, yposmin, 1])
ax.xaxis.set_major_locator(MaxNLocator(integer=True))
ax.add_line(
......@@ -641,12 +651,12 @@ class Schedule:
def _reset_y_locations(self):
self._y_locations = self._y_locations = defaultdict(lambda: None)
def plot_schedule(self) -> None:
self._get_figure().show()
def plot_schedule(self, operation_gap=None) -> None:
self._get_figure(operation_gap=operation_gap).show()
def _get_figure(self):
def _get_figure(self, operation_gap=None) -> None:
fig, ax = plt.subplots()
self._plot_schedule(ax)
self._plot_schedule(ax, operation_gap=operation_gap)
return fig
def _repr_svg_(self):
......
......@@ -14,3 +14,6 @@ OPERATION_LATENCY_INACTIVE = QColor(*LATENCY_COLOR)
OPERATION_LATENCY_ACTIVE = QColor(0, 207, 181)
OPERATION_EXECUTION_TIME_INACTIVE = QColor(*EXECUTION_TIME_COLOR)
OPERATION_EXECUTION_TIME_ACTIVE = QColor(*EXECUTION_TIME_COLOR)
OPERATION_HEIGHT = 0.75
OPERATION_GAP = 0.25
......@@ -14,10 +14,10 @@ from typing import Dict, List, Optional, Set, cast
from qtpy.QtWidgets import QGraphicsItem, QGraphicsItemGroup
# B-ASIC
from b_asic._preferences import OPERATION_GAP
from b_asic.operation import Operation
from b_asic.port import InputPort
from b_asic.schedule import Schedule
from b_asic.scheduler_gui._preferences import OPERATION_GAP, OPERATION_HEIGHT
from b_asic.scheduler_gui.axes_item import AxesItem
from b_asic.scheduler_gui.operation_item import OperationItem
from b_asic.scheduler_gui.scheduler_event import SchedulerEvent
......@@ -31,6 +31,15 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5
AxesItem, as well as components from OperationItem. It
also inherits from SchedulerEvent, which acts as a filter for events
to OperationItem objects.
Parameters
==========
schedule : Schedule
The Schedule to draw.
parent : QGraphicsItem, optional
The parent. Passed to the constructor of QGraphicsItemGroup
"""
_axes: Optional[AxesItem]
......@@ -42,7 +51,7 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5
def __init__(
self, schedule: Schedule, parent: Optional[QGraphicsItem] = None
):
"""Constructs a SchedulerItem. 'parent' is passed to QGraphicsItemGroup's constructor.
"""Constructs a SchedulerItem. *parent* is passed to QGraphicsItemGroup's constructor.
"""
# QGraphicsItemGroup.__init__(self, self)
# SchedulerEvent.__init__(self)
......@@ -60,7 +69,8 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5
self._make_graph()
def clear(self) -> None:
"""Sets all children's parent to 'None' and delete the children objects.
"""
Sets all children's parent to 'None' and delete the children objects.
"""
self._event_items = []
for item in self.childItems():
......@@ -68,8 +78,19 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5
del item
def is_component_valid_pos(self, item: OperationItem, pos: float) -> bool:
"""Takes in a component position and returns true if the component's new
position is valid, false otherwise."""
"""
Takes in a component position and returns true if the component's new
position is valid, false otherwise.
Parameters
==========
item : OperationItem
The component.
pos : float
The x-position to check.
"""
# TODO: implement
assert self.schedule is not None, "No schedule installed."
end_time = item.end_time
......@@ -94,24 +115,43 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5
return True
def _redraw_all_lines(self):
def _redraw_all_lines(self) -> None:
"""Redraw all lines in schedule."""
s = set()
for signals in self._signal_dict.values():
s.update(signals)
for signal in s:
signal.update_path()
def _redraw_lines(self, item: OperationItem):
def _redraw_lines(self, item: OperationItem) -> None:
"""Update lines connected to *item*."""
for signal in self._signal_dict[item]:
signal.update_path()
def set_item_active(self, item: OperationItem):
def set_item_active(self, item: OperationItem) -> None:
"""
Set an item as active, i.e., draw it and connecting signals in special colors.
Parameters
----------
item : OperationItem
The item to set as active.
"""
item.set_active()
for signal in self._signal_dict[item]:
signal.set_active()
def set_item_inactive(self, item: OperationItem):
def set_item_inactive(self, item: OperationItem) -> None:
"""
Set an item as inactive, i.e., draw it and connecting signals in standard colors.
Parameters
----------
item : OperationItem
The item to set as active.
"""
item.set_inactive()
for signal in self._signal_dict[item]:
signal.set_inactive()
......@@ -126,8 +166,9 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5
self.schedule.move_operation(item.graph_id, move_time)
def is_valid_delta_time(self, delta_time: int) -> bool:
"""Takes in a delta time and returns true if the new schedule time is
valid, false otherwise."""
"""
Takes in a delta time and returns True if the schedule time can be changed by *delta_time*. False otherwise.
"""
# TODO: implement
# item = self.scene().mouseGrabberItem()
assert self.schedule is not None, "No schedule installed."
......@@ -137,7 +178,7 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5
)
def set_schedule_time(self, delta_time: int) -> None:
"""Set the schedule time and redraw the graph."""
"""Change the schedule time by *delta_time* and redraw the graph."""
if self._axes is None:
raise RuntimeError("No AxesItem!")
assert self.schedule is not None, "No schedule installed."
......@@ -170,7 +211,9 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5
op_item = self._operation_items[graph_id]
op_item.setPos(
self._x_axis_indent + self.schedule.start_times[graph_id],
self.schedule._get_y_position(graph_id),
self.schedule._get_y_position(
graph_id, OPERATION_HEIGHT, OPERATION_GAP
),
)
def _redraw_from_start(self) -> None:
......@@ -190,21 +233,25 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5
max_pos_graph_id = max(
self.schedule._y_locations, key=self.schedule._y_locations.get
)
yposmin = self.schedule._get_y_position(max_pos_graph_id)
yposmin = self.schedule._get_y_position(
max_pos_graph_id, OPERATION_HEIGHT, OPERATION_GAP
)
if self._axes is None or build:
self._axes = AxesItem(schedule_time, yposmin + 0.5)
self._event_items += self._axes.event_items
else:
self._axes.set_height(yposmin + 0.5)
self._axes.setPos(0, yposmin + 1 + OPERATION_GAP)
self._axes.setPos(0, yposmin + OPERATION_HEIGHT + OPERATION_GAP)
def _make_graph(self) -> None:
"""Makes a new graph out of the stored attributes."""
# build components
for graph_id in self.schedule.start_times.keys():
operation = cast(Operation, self.schedule.sfg.find_by_id(graph_id))
component = OperationItem(operation, parent=self)
component = OperationItem(
operation, height=OPERATION_HEIGHT, parent=self
)
self._operation_items[graph_id] = component
self._set_position(graph_id)
self._event_items += component.event_items
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment