-
Notifications
You must be signed in to change notification settings - Fork 100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(4->3) Add GUI Elements for Interacting With RecordingSession
#1283
Open
roomrys
wants to merge
64
commits into
liezl/asc-initial-update-instances-across-views
Choose a base branch
from
liezl/add-gui-elements-for-sessions
base: liezl/asc-initial-update-instances-across-views
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
(4->3) Add GUI Elements for Interacting With RecordingSession
#1283
roomrys
wants to merge
64
commits into
liezl/asc-initial-update-instances-across-views
from
liezl/add-gui-elements-for-sessions
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…iezl/iuiav-fix-(de)-serialization
…ps://github.com/talmolab/sleap into liezl/iuiav-fix-(de)-serialization
…ps://github.com/talmolab/sleap into liezl/iuiav-fix-(de)-serialization
roomrys
changed the base branch from
develop
to
liezl/iuiav-fix-(de)-serialization
April 20, 2023 16:32
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## liezl/asc-initial-update-instances-across-views #1283 +/- ##
===================================================================================
+ Coverage 73.99% 74.18% +0.19%
===================================================================================
Files 135 135
Lines 24923 25450 +527
===================================================================================
+ Hits 18441 18881 +440
- Misses 6482 6569 +87 ☔ View full report in Codecov by Sentry. |
…elements-for-sessions
…iezl/iuiav-fix-(de)-serialization
…elements-for-sessions
roomrys
changed the title
Add GUI Elements for Interacting With
(5->4) Add GUI Elements for Interacting With Jul 6, 2023
RecordingSession
RecordingSession
…iezl/iuiav-fix-(de)-serialization
…elements-for-sessions
Base automatically changed from
liezl/iuiav-fix-(de)-serialization
to
liezl/asc-initial-update-instances-across-views
September 29, 2023 20:22
roomrys
changed the title
(5->4) Add GUI Elements for Interacting With
(4->3) Add GUI Elements for Interacting With Sep 29, 2023
RecordingSession
RecordingSession
…ps://github.com/talmolab/sleap into liezl/add-gui-elements-for-sessions
roomrys
force-pushed
the
liezl/add-gui-elements-for-sessions
branch
from
October 13, 2023 23:27
9771ff5
to
2c9ea0c
Compare
…iezl/add-gui-elements-for-sessions
* add attributes for instance groups and take argument of current session and frame index * change the naming convention for frame index * finished the get_color method * fixed color.py according to the comments and styling, and new tests added * added additional test * lint * added a toggle button * Lint * FIx logic for coloring by instance groups * refined some logics for the color.py * Lint * disable color predicted if color by instance groups is selected * deleted unnecessary code * updated comments * initialized instance group to None and add another logic * Revert "Merge branch 'andrew/color-by-instance-groups' of https://github.com/talmolab/sleap into andrew/color-by-instance-groups" This reverts commit afb53ec, reversing changes made to 75e2a0d. * Color instances that are not in group a certain color * Replot the frame (to update coloring) when SetInstanceGroup * Remove unused import * Remove old TODO --------- Co-authored-by: roomrys <[email protected]>
* Add instance group dock * Change Frame_idx column name to Frame Index * Add additional logic for when frame has no InstanceGroup and callback when frame changes * Add get_instance_group_color method to ColorManager * Color items in "Name" column when distinctly coloring instance groups --------- Co-authored-by: roomrys <[email protected]>
* Re-encode multiview videos * Trigger tests * Remove unused code
* Set the video state to unlinked video state --------- Co-authored-by: roomrys <[email protected]>
* Add TODO comment * Add visual indicator for current camera * Add change to print Camcorder.name * Ensure session state is updated as first callback of video state --------- Co-authored-by: Jvshen <[email protected]> Co-authored-by: Liezl Maree <[email protected]>
* created logics for automatic addition of videos * not display import messages when no videos are found in the directory * Update test_commands.py * deleted unnecessary codes and manual testing worked perfectly * Split up ask and do methods based on GUI interaction * Find video paths using calibration only * Add fixture for calibration directory * Test automatic addition of videos --------- Co-authored-by: roomrys <[email protected]>
* Modify switch_frame function to stay on same frame if video has enough frames * Simplify logic --------- Co-authored-by: roomrys <[email protected]>
* Add id property to RecordingSession * Add small test
…1825) * overrided the activateSelected function for cameras table * video is switched whenever an item in the CamerasTable is double-clicked * Handle case when camera is None --------- Co-authored-by: roomrys <[email protected]>
* Link videos to cameras when add session * Typehinting * Add checks on input argument types * Test CommandContext.linkVideoToSession * Add test to link video to session when add session
* Test that points are always updated if predicted or not visible * Always update points if predicted or not visible
* Move compute_oks function to utils (avoid circular import) * Update InstanceGroup score when update_points * Add score to InstanceGroup repr * Add score to InstanceGroup table * (De)Serialize new score attribute * Add more docs on score attribute * Test score attribute
* Add editing feature for InstanceGroup.name * Add changes for editing feature for InstanceGroup.name * Add changes for editing feature for InstanceGroup.name * Lint * Add minimal test --------- Co-authored-by: roomrys <[email protected]>
* Enforce projection bounds * Test projection_bounds propert of RecordingSession * Test upsert_points method of FrameGroup * Only return bounds for cams_to_include * Expose invisible_as_nan argument to FrameGroup.numpy * Ensure that numpy array is filled with float values in FrameGroup.upsert_points * Add a cached RecordingSession._projection_bounds attribute * Add a tests for the cached projection_bounds * Lint
* Add connect callback to instance group * Add QtInstance instead of InstanceGroup * Add changes for review * Handle case when select is neither Instance, int, nor InstanceGroup --------- Co-authored-by: roomrys <[email protected]>
This problem goes deeper than expected and needs a Pull Request
* Add Color by Instance Group preference saving * Replaced color_by_instance_group with distinctly_color to align with the existing View > Apply Distinct Colors To submenu * Use updated preference for GUI state * Rename GUI facing "instance_groups" to "instance groups" --------- Co-authored-by: roomrys <[email protected]>
Update "instance" state as "frame_idx" callback
4 tasks
* Check if predicted instance is removed that it's not referenced * Add manual test for removing predicted instance * Add comment for develop merge --------- Co-authored-by: Liezl Maree <[email protected]>
* Do not sort keys when loading calibration toml * Test that cameras are loaded in original order
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
This is a pretty large PR that aims to do a few high-level GUI tasks:
SessionsDock
(for all/mostRecordingSession
-related GUI items)RecordingSession
s table toSessionsDock
#1654 (@vaibhavtrip29)CamerasTable
toSessionsDock
#1671 (@AdvaithRavishankar)UnlinkedVideosTable
toSessionsDock
#1720 (@7174Andy)Instance
to anInstanceGroup
#1747 (@ramizhajj1)InstanceGroup
option #1760 (@7174Andy)See the subsections below for more detailed mini-tasks:
Add SesssionsDock
SessionsDock
which has a button for triangulation (and checkbox for auto-triangulation)SessionsDock
to GUIGuiState
forauto_triangulate == True
)Allow navigate between views
Alt+V
andAlt+Shift+V
and store in shortcuts.yamlOnly update "incomplete" nodes
Add
RecordingSession
table toSessionsDock
(#1654)The overall goal here is to add a new table to the
SessionsDock
that displays allRecordingSession
s in theSessionsDock.main_window.label.sessions: List[RecordingSession]
list. The widget should be a table that displays theRecordingSession
s hash (eventually name), number ofRecordingSession.cameras: List[Camcorder]
, and number ofRecordingSession.videos: List[Video]
(see Figure 1). ThisSessionsTable
will be used to dynamically populate ourCamerasTable
later on.GenericTableModel
to create a new model calledSessionsTableModel
with the class attributeproperties = ("id", "videos", "cameras")
(similar toVideosTableModel
)SessionsTableModel.item_to_data(self, obj: List[RecordingSession], item: RecordingSession)
which returns the following dictionary:{id: item.__hash__(), videos: len(item.videos), cameras: len(item.cameras)}
(similar toVideosTableModel.item_to_data
)sessions_model_type = SessionsTableModel
attribute toSessionsDock
(similar toSkeletonDock.nodes_model_type
) and pass into themodel_type
list forsuper().__init__
SessionsDock.create_models
method (or append to it if it already exists) that sets aSessionsDock.sessions_model = SessionsDock.sessions_model_type(items=main_window.state["labels"].sessions, context=main_window.commands)
and returns a list of all models created (seeSkeletonDock.create_models
)SessionsDock.create_tables
method (or append to it if it already exists) that sets aSessionsDock.sessions_table = GenericTableView(state=..., row_name="session", ...)
and returns a list of all tables created (seeSkeletonDock.create_tables
)RecordingSession
SessionsDock.lay_everything_out
method, add theSessionsDock.sessions_table
to theSessionsDock.wgt_layout: QVBoxLayout
(see theInstancesDock.lay_everything_out
).sessions
option toUpdateTopic: Enum
MainWindow.on_data_update
add (or append to) theif _has_topic(UpdateTopic.sessions)
that updates the items to display in theSessionsTable
(seevideo_dock.table
update)Test the
SessionsTable
Tests for the
SessionsTable
will be added totests/gui/test_dataviews.py
.RecordingSession
is returned when we select a specific row of the table (see existing test for inspiration)RecordingSession
inlabels.sessions
, theRecordingSession
in the table is updated as wellTest the
SessionsTable
as part of theSessionsDock
Tests for the
SessionsDock
will be added totests/gui/widgets/test_docks.py
.GuiState
(see existing test)Figure 1: Depiction of all tables to add, including
SessionsTable
,CamerasTable
, andUnlinkedVideosTable
.Add
CamerasTable
toSessionsDock
The overall goal is to add
Camcorder
/Video
assignment table to theSessionsDock
that is linked to theSessionsTable
created above. ThisCamerasTable
will have two columns. One column will display theCamcorder.name
s of allCamcorder
s in theRecordingSession.cameras: List[Camcorder]
list. The second column will show whichVideo
s are assigned to the adjacentCamcorder.name
by displaying the returned value ofRecordingSession.get_video(Camcorder)
(or""
ifNone
).GenericTableModel
to create a new model calledCamerasTableModel
withproperties = ("camera", "video")
CamerasTableModel.object_to_items(self, obj: RecordingSession)
which returns the list ofCamcorder
s inobj.cameras: List[Camcorder]
CamerasTableModel.item_to_data(self, obj: RecordingSession, item: Camcorder)
which returns the following dictionary:{camera: item.name, video: obj.get_video(item)}
cameras_model_type = CamerasTableModel
attribute toSessionsDock
(similar toSkeletonDock.nodes_model_type
) and pass into themodel_type
list forsuper().__init__
SessionsDock.create_models
method (or append to it if it already exists) that sets aSessionsDock.cameras_model = SessionsDock.sessions_model_type(items=main_window.state["selected_session"], context=main_window.commands)
and returns a list of all models created (seeSkeletonDock.create_models
)SessionsDock.create_tables
method (or append to it if it already exists) that sets aSessionsDock.cameras_table = GenericTableView(state=..., row_name="camera", ...)
and returns a list of all tables created (seeSkeletonDock.create_tables
)CommandContext.unlink_video_from_camera
method to un-link aVideo
from aCamcorder
CommandContext.unlink_video_from_camera
methodCamcorder
for theCamerasTable
SessionsDock.lay_everything_out
method, add theSessionsDock.cameras_table
to theSessionsDock.wgt_layout: QVBoxLayout
(see theInstancesDock.lay_everything_out
).sessions
option toUpdateTopic: Enum
if not already thereMainWindow.on_data_update
add (or append to) theif _has_topic(UpdateTopic.sessions)
that updates the items to display in theCamerasTable
(seevideo_dock.table
update)Test the
CamerasTable
Tests for the
CamerasTable
will be added totests/gui/test_dataviews.py
. These tests will only test the functionality of the table as it's own entity.Camcorder
is returned when we select a specific row of the table (see existing test for inspiration)Camcorder
inlabels.sessions
, theCamcorder
in the table is updated as wellTest the
CamerasTable
as part of theSessionsDock
Tests for the
SessionsDock
will be added totests/gui/widgets/test_docks.py
.GuiState
(see existing test)Add
UnlinkedVideosTable
toSessionsDock
Very similar steps to
SessionsTable
andCamerasTable
(to be filled in), except for these few items:{linked: ..., unlinked: ...}
toLabelsDataCache
that remembers which videos are linked/unlinked to aRecordingSession
inlabels.sessions
(this dictionary will be used for the items in theUnlinkedVideosTable
)CommandContext.link_video_to_camera
method to link aVideo
to aRecordingSession
CommandContext
method created above)Assign
Instance
to anInstanceGroup
(waiting on 3a-3f to be merged)sessionsMenu
named "Sessions" (similar to thetracksMenu
)self.inst_groups_menu
attribute to theMainWindow
that adds a menu to thesessionsMenu
called "Set Instance Group" (similar toself.track_menu
)self.inst_groups_menu
whenhas_selected_instance == True
(similar toself.track_menu
)MainWindow._update_sessions_menu
method that takes inself
andframe_idx
, then retrieves thesession: Optional[RecordingSession] = self.state["session"]
and theframe_group: FrameGroup = session.frame_groups[frame_idx]
. First clear theself.inst_groups_menu
. Then, enumerate through allinstance_groups
inframe_group.instance_groups: List[InstanceGroup]
. For the first 9InstanceGroup
s use thekey_command = Qt.SHIFT + Qt.Key_0 + inst_group_ind + 1
(otherwise use a defaultkey_command = ""
). For allinstance_groups
, add aself.inst_groups_menu
action with nameinstance_group.name
, callbacklambda x=instance_group: self.commands.setInstanceGroup(x)
, and shortcut ofkey_command
. Outside the enumeration, add a"New Instance Group"
action to theself.inst_groups_menu
with name"New Instance Group"
, callbackself.commands.addInstanceGroup
, and hotkeyQt.SHIFT + Qt.Key_0
. Very similar toMainWindow._update_track_menu
.CommandContext.setInstanceGroup(self, instance_group: Optional[InstanceGroup])
method that executes theSetSelectedInstanceGroup
class with inputinstance_group=instance_group
(seeCommandContext.setInstanceTrack
).CommandContext.addInstanceGroup(self)
method that executes theAddInstanceGroup
class (seeCommandContext.addTrack
).sleap/gui/commands.py
add aSetSelectedInstanceGroup
class that subclassesEditCommand
. Add aSetSelectedInstanceGroup.do_action(context, params)
staticmethod that first retrieves theselected_instance = context.state[selected_instance]
,frame_idx: int = context.state["frame_idx"]
,video: Video = context.state["video"]
,session: RecordingSession = context.state["session"]
,frame_group: FrameGroup = session.frame_groups.get(frame_idx, None)
, andcamera = session.get_camera(video=video)
. You will need to useframe_group = session.new_frame_group(frame_idx=frame_idx)
ifframe_group is None
. Then, useframe_group.add_instance(instance=selected_instance, camera=camera, instance_group=instance_group)
to add theselected_instance
to theinstance_group
(andframe_group
). Similar to theSetSelectedInstanceTrack
class.sleap/gui/commands.py
add aAddInstanceGroup
class that subclassesEditCommand
. Add aAddInstanceGroup.do_action(context, params)
staticmethod that first retrieves theframe_idx: int = context.state["frame_idx"]
,session: RecordingSession = context.state["session"]
, andframe_group: FrameGroup = session.frame_groups[frame_idx]
. Then, useframe_group.add_instance_group(instance_group=None)
to create and add a new emptyInstanceGroup
to theframe_group
. Similar to theAddTrack
class.Using the workflow above (but with less detailed write-up), please also:
Figure 2: GUI elements for assigning
Instance
s toInstanceGroup
s will be similar to how we assignInstance
s toTrack
s.Types of changes
Does this address any currently open issues?
[list open issues here]
Outside contributors checklist
Thank you for contributing to SLEAP!
❤️