-
Notifications
You must be signed in to change notification settings - Fork 11
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
Adding support for more .nwb training data to SLEAP #104
Open
keyaloding
wants to merge
92
commits into
talmolab:main
Choose a base branch
from
keyaloding:kloding/nwb_data_structures
base: main
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
Changes from 20 commits
Commits
Show all changes
92 commits
Select commit
Hold shift + click to select a range
70a34ed
nwb to sleap conversion function
keyaloding f2fd6f5
push
keyaloding 6c062ec
fixed attribute errors
keyaloding f7d8a0c
test
keyaloding 23a5a83
b
keyaloding cf4bcf7
n
keyaloding 8948e92
a
keyaloding be6ccbc
message
keyaloding 0aabd86
update
keyaloding 85d47ab
change
keyaloding 1b8e08b
black
keyaloding aab5a79
cab
keyaloding 66edcd6
update
keyaloding 1b70d5c
change
keyaloding c59f996
m
keyaloding 50da4a1
black
keyaloding c8c173a
black
keyaloding 0742bdf
updated skeleton naming
keyaloding 055e3e8
updated package handling
keyaloding dcc3da8
added error handling
keyaloding 0ba071e
`append_nwb_training` update
keyaloding 0c7f048
added test
keyaloding 6a6c38c
Merge branch 'talmolab:main' into kloding/nwb_data_structures
keyaloding b15471e
Code quality
keyaloding dd522f9
resolved some comments
keyaloding 22ed734
resolved comments + formatting
keyaloding 7d1737d
updated test and fixed comments
keyaloding 6f1a7d1
added img_to_path function (not implemented)
keyaloding 51d5623
updated img_to_path
keyaloding e511efa
img_to_path
keyaloding 42da933
added test and finished img_to_path
keyaloding e246f8b
removed slp_pkg function and code quality
keyaloding 13d3a47
attempted to resolve `Skeletons` issue and nwbfile version
keyaloding e579ebf
updated load_nwb and video writing
keyaloding 90f0ec4
updated processing module handling
keyaloding 24634a1
update
keyaloding 4819536
fixed save issues
keyaloding 432c343
updated saving
keyaloding 7cb04c4
updated code quality and image write function
keyaloding a66cf8f
implemented metadata indexing
keyaloding 8f2271b
updated loading nwb
keyaloding f510765
black
keyaloding 183cf55
updated video handling
keyaloding 7e2d138
added `__future__` import
keyaloding 846856b
updated future import
keyaloding f88ca17
updated test and documentation
keyaloding 0a8fc45
updated saving nwb
keyaloding 73b41b0
Revert "updated video handling"
keyaloding a9be0eb
Delete save_test.ipynb
keyaloding 1031247
added test fixtures
keyaloding 68c7cfb
fixed recursion error
keyaloding 3bf7c8a
updated error handling
keyaloding 6d12f39
updated error handling
keyaloding e94c14d
code quality
keyaloding dac1eb5
code quality
keyaloding 593c139
code quality
keyaloding 68133e1
code quality
keyaloding d66b858
updated video saving
keyaloding 0abaca4
deleted large test file
keyaloding 4ba67ea
updated video loading and pose_estimation creation
keyaloding 3bac601
reverted PoseEstimation handling
keyaloding 9699be2
updated fixtures
keyaloding f01e03a
updated fixtures
keyaloding 9a4422d
Delete load_test.ipynb
keyaloding 55ca394
Delete presentation.ipynb
keyaloding c91e74c
code quality
keyaloding 63faf8b
code quality
keyaloding 56911d6
fixed pydocstyle errors
keyaloding ac6bb23
updated tests
keyaloding 0be5813
a
keyaloding 46f63c6
fixed test not passing
keyaloding 1cd6180
fixed test not passing
keyaloding a2f96ab
update
keyaloding 30fbe6f
added cameras
keyaloding 6a0cf27
fixed test fixture
keyaloding 52d45b8
added fixture
keyaloding bab0917
updated tests
keyaloding a268e1f
update
keyaloding c57e572
updated toml
keyaloding e7b9fd3
z
keyaloding e932340
camera update
keyaloding 6f3aabe
fixed OrphanBuildContainerError
keyaloding 7a83046
one test left
keyaloding 1a7e58b
passed all tests
keyaloding 90fd397
removed unused function
keyaloding d8294b7
removed unused function
keyaloding c3b286e
Merge branch 'talmolab:main' into kloding/nwb_data_structures
keyaloding dedc06d
code quality update, removed `PoseEstimation` handling
keyaloding 141d1dd
fixed black format issue
keyaloding 67a62c2
added `SkeletonInstance` counter
keyaloding bf7fadf
Docs and nits
talmo 62dc540
Add multi-video support
talmo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 1, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"%load_ext autoreload\n", | ||
"%autoreload 2\n", | ||
"import sleap_io as sio\n", | ||
"import pynwb\n", | ||
"import numpy as np\n", | ||
"from numpy.testing import assert_equal\n", | ||
"from sleap_io import save_file\n", | ||
"from sleap_io.model.skeleton import Node, Edge, Symmetry, Skeleton\n", | ||
"from sleap_io.model.instance import *\n", | ||
"from pynwb.image import ImageSeries\n", | ||
"from ndx_pose import (\n", | ||
" PoseEstimation,\n", | ||
" PoseEstimationSeries,\n", | ||
" TrainingFrame,\n", | ||
" TrainingFrames,\n", | ||
" PoseTraining,\n", | ||
" SourceVideos,\n", | ||
")\n", | ||
"from sleap_io.io.nwb import *" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"Labels(labeled_frames=1, videos=1, skeletons=1, tracks=0, suggestions=0)\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"labels_original = sio.load_slp(\"tests/data/slp/minimal_instance.pkg.slp\")\n", | ||
"skel = Skeleton([Node(\"A\"), Node(\"B\")])\n", | ||
"skel.name = \"name\"\n", | ||
"skel.edges = [Edge(Node(\"A\"), Node(\"B\"))]\n", | ||
"slp_skeleton_to_nwb(skel)\n", | ||
"\n", | ||
"inst = Instance({\"A\": [0, 1], \"B\": [2, 3]}, skeleton=Skeleton([\"A\", \"B\"]))\n", | ||
"inst.skeleton.name = \"name\"\n", | ||
"inst.skeleton.edges = [Edge(Node(\"A\"), Node(\"B\"))]\n", | ||
"instance_to_skeleton_instance(inst)\n", | ||
"\n", | ||
"pose = labels_to_pose_training(labels_original)\n", | ||
"labels = pose_training_to_labels(pose)\n", | ||
"print(labels)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 7, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"ename": "KeyError", | ||
"evalue": "'tests/data/slp/minimal_instance.pkg.slp'", | ||
"output_type": "error", | ||
"traceback": [ | ||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", | ||
"\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", | ||
"Cell \u001b[0;32mIn[7], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m labels_original \u001b[38;5;241m=\u001b[39m sio\u001b[38;5;241m.\u001b[39mload_slp(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtests/data/slp/minimal_instance.pkg.slp\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m----> 2\u001b[0m \u001b[43mlabels_original\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msave\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mminimal_instance.pkg.nwb\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mformat\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mnwb_training\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 4\u001b[0m labels_loaded \u001b[38;5;241m=\u001b[39m sio\u001b[38;5;241m.\u001b[39mload_nwb(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtests/data/slp/minimal_instance.pkg.nwb\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28mprint\u001b[39m(labels_loaded)\n", | ||
"File \u001b[0;32m~/salk/io_fork/sleap_io/model/labels.py:372\u001b[0m, in \u001b[0;36mLabels.save\u001b[0;34m(self, filename, format, embed, **kwargs)\u001b[0m\n\u001b[1;32m 348\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Save labels to file in specified format.\u001b[39;00m\n\u001b[1;32m 349\u001b[0m \n\u001b[1;32m 350\u001b[0m \u001b[38;5;124;03mArgs:\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 368\u001b[0m \u001b[38;5;124;03m This argument is only valid for the SLP backend.\u001b[39;00m\n\u001b[1;32m 369\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 370\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01msleap_io\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m save_file\n\u001b[0;32m--> 372\u001b[0m \u001b[43msave_file\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfilename\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mformat\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mformat\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43membed\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43membed\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", | ||
"File \u001b[0;32m~/salk/io_fork/sleap_io/io/main.py:235\u001b[0m, in \u001b[0;36msave_file\u001b[0;34m(labels, filename, format, **kwargs)\u001b[0m\n\u001b[1;32m 233\u001b[0m save_slp(labels, filename, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 234\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mformat\u001b[39m \u001b[38;5;129;01min\u001b[39;00m (\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnwb\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnwb_training\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnwb_predictions\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[0;32m--> 235\u001b[0m \u001b[43msave_nwb\u001b[49m\u001b[43m(\u001b[49m\u001b[43mlabels\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfilename\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 236\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mformat\u001b[39m \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mlabelstudio\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[1;32m 237\u001b[0m save_labelstudio(labels, filename, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", | ||
"File \u001b[0;32m~/salk/io_fork/sleap_io/io/main.py:86\u001b[0m, in \u001b[0;36msave_nwb\u001b[0;34m(labels, filename, as_training, append, **kwargs)\u001b[0m\n\u001b[1;32m 84\u001b[0m nwb\u001b[38;5;241m.\u001b[39mappend_nwb(labels, filename, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 85\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m---> 86\u001b[0m \u001b[43mnwb\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mwrite_nwb\u001b[49m\u001b[43m(\u001b[49m\u001b[43mlabels\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfilename\u001b[49m\u001b[43m)\u001b[49m\n", | ||
"File \u001b[0;32m~/salk/io_fork/sleap_io/io/nwb.py:408\u001b[0m, in \u001b[0;36mwrite_nwb\u001b[0;34m(labels, nwbfile_path, nwb_file_kwargs, pose_estimation_metadata)\u001b[0m\n\u001b[1;32m 401\u001b[0m nwb_file_kwargs\u001b[38;5;241m.\u001b[39mupdate(\n\u001b[1;32m 402\u001b[0m session_description\u001b[38;5;241m=\u001b[39msession_description,\n\u001b[1;32m 403\u001b[0m session_start_time\u001b[38;5;241m=\u001b[39msession_start_time,\n\u001b[1;32m 404\u001b[0m identifier\u001b[38;5;241m=\u001b[39midentifier,\n\u001b[1;32m 405\u001b[0m )\n\u001b[1;32m 407\u001b[0m nwbfile \u001b[38;5;241m=\u001b[39m NWBFile(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mnwb_file_kwargs)\n\u001b[0;32m--> 408\u001b[0m nwbfile \u001b[38;5;241m=\u001b[39m \u001b[43mappend_nwb_data\u001b[49m\u001b[43m(\u001b[49m\u001b[43mlabels\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnwbfile\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpose_estimation_metadata\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 410\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m NWBHDF5IO(\u001b[38;5;28mstr\u001b[39m(nwbfile_path), \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mw\u001b[39m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;28;01mas\u001b[39;00m io:\n\u001b[1;32m 411\u001b[0m io\u001b[38;5;241m.\u001b[39mwrite(nwbfile)\n", | ||
"File \u001b[0;32m~/salk/io_fork/sleap_io/io/nwb.py:491\u001b[0m, in \u001b[0;36mappend_nwb_data\u001b[0;34m(labels, nwbfile, pose_estimation_metadata)\u001b[0m\n\u001b[1;32m 487\u001b[0m default_metadata\u001b[38;5;241m.\u001b[39mupdate(pose_estimation_metadata)\n\u001b[1;32m 489\u001b[0m \u001b[38;5;66;03m# For every track in that video create a PoseEstimation container\u001b[39;00m\n\u001b[1;32m 490\u001b[0m name_of_tracks_in_video \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m--> 491\u001b[0m \u001b[43mlabels_data_df\u001b[49m\u001b[43m[\u001b[49m\u001b[43mvideo\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfilename\u001b[49m\u001b[43m]\u001b[49m\n\u001b[1;32m 492\u001b[0m \u001b[38;5;241m.\u001b[39mcolumns\u001b[38;5;241m.\u001b[39mget_level_values(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtrack_name\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 493\u001b[0m \u001b[38;5;241m.\u001b[39munique()\n\u001b[1;32m 494\u001b[0m )\n\u001b[1;32m 496\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m track_name \u001b[38;5;129;01min\u001b[39;00m name_of_tracks_in_video:\n\u001b[1;32m 497\u001b[0m pose_estimation_container \u001b[38;5;241m=\u001b[39m build_pose_estimation_container_for_track(\n\u001b[1;32m 498\u001b[0m labels_data_df,\n\u001b[1;32m 499\u001b[0m labels,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 502\u001b[0m default_metadata,\n\u001b[1;32m 503\u001b[0m )\n", | ||
"File \u001b[0;32m~/mambaforge3/envs/io_dev/lib/python3.12/site-packages/pandas/core/frame.py:4102\u001b[0m, in \u001b[0;36mDataFrame.__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 4100\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcolumns\u001b[38;5;241m.\u001b[39mnlevels \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[1;32m 4101\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_getitem_multilevel(key)\n\u001b[0;32m-> 4102\u001b[0m indexer \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcolumns\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_loc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 4103\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m is_integer(indexer):\n\u001b[1;32m 4104\u001b[0m indexer \u001b[38;5;241m=\u001b[39m [indexer]\n", | ||
"File \u001b[0;32m~/mambaforge3/envs/io_dev/lib/python3.12/site-packages/pandas/core/indexes/range.py:417\u001b[0m, in \u001b[0;36mRangeIndex.get_loc\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 415\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(key) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01merr\u001b[39;00m\n\u001b[1;32m 416\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(key, Hashable):\n\u001b[0;32m--> 417\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(key)\n\u001b[1;32m 418\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_check_indexing_error(key)\n\u001b[1;32m 419\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(key)\n", | ||
"\u001b[0;31mKeyError\u001b[0m: 'tests/data/slp/minimal_instance.pkg.slp'" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"labels_original = sio.load_slp(\"tests/data/slp/minimal_instance.pkg.slp\")\n", | ||
"labels_original.save(\"minimal_instance.pkg.nwb\", format=\"nwb_training\")\n", | ||
"\n", | ||
"labels_loaded = sio.load_nwb(\"tests/data/slp/minimal_instance.pkg.nwb\")\n", | ||
"print(labels_loaded)\n", | ||
"assert len(labels_original.labeled_frames) == len(labels_loaded.labeled_frames)\n", | ||
"assert len(labels_original.videos) == len(labels_loaded.videos)\n", | ||
"assert len(labels_original.skeletons) == len(labels_loaded.skeletons)\n", | ||
"assert len(labels_original.tracks) == len(labels_loaded.tracks)\n", | ||
"assert len(labels_original.suggestions) == len(labels_loaded.suggestions)\n", | ||
"assert labels_original.provenance == labels_loaded.provenance" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "io_dev", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.12.4" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 1, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"%load_ext autoreload\n", | ||
"%autoreload 2" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"minimal_instance.pkg.nwb_images/img_0.png\n" | ||
] | ||
}, | ||
{ | ||
"ename": "ValueError", | ||
"evalue": "Can't write images with one color channel.", | ||
"output_type": "error", | ||
"traceback": [ | ||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", | ||
"\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", | ||
"Cell \u001b[0;32mIn[2], line 16\u001b[0m\n\u001b[1;32m 14\u001b[0m img_path \u001b[38;5;241m=\u001b[39m save_path \u001b[38;5;241m/\u001b[39m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mimg_\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mi\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m.png\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 15\u001b[0m \u001b[38;5;28mprint\u001b[39m(img_path)\n\u001b[0;32m---> 16\u001b[0m \u001b[43miio\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mimwrite\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimg_path\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlf\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mimage\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 17\u001b[0m img_paths\u001b[38;5;241m.\u001b[39mappend(img_path)\n\u001b[1;32m 18\u001b[0m \u001b[38;5;28mprint\u001b[39m(img_paths)\n", | ||
"File \u001b[0;32m~/mambaforge3/envs/io_dev/lib/python3.12/site-packages/imageio/v3.py:147\u001b[0m, in \u001b[0;36mimwrite\u001b[0;34m(uri, image, plugin, extension, format_hint, **kwargs)\u001b[0m\n\u001b[1;32m 105\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Write an ndimage to the given URI.\u001b[39;00m\n\u001b[1;32m 106\u001b[0m \n\u001b[1;32m 107\u001b[0m \u001b[38;5;124;03mThe exact behavior depends on the file type and plugin used. To learn about\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 136\u001b[0m \n\u001b[1;32m 137\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 139\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m imopen(\n\u001b[1;32m 140\u001b[0m uri,\n\u001b[1;32m 141\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mw\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 145\u001b[0m extension\u001b[38;5;241m=\u001b[39mextension,\n\u001b[1;32m 146\u001b[0m ) \u001b[38;5;28;01mas\u001b[39;00m img_file:\n\u001b[0;32m--> 147\u001b[0m encoded \u001b[38;5;241m=\u001b[39m \u001b[43mimg_file\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mwrite\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimage\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 149\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m encoded\n", | ||
"File \u001b[0;32m~/mambaforge3/envs/io_dev/lib/python3.12/site-packages/imageio/plugins/pillow.py:433\u001b[0m, in \u001b[0;36mPillowPlugin.write\u001b[0;34m(self, ndimage, mode, format, is_batch, **kwargs)\u001b[0m\n\u001b[1;32m 431\u001b[0m is_batch \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[1;32m 432\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m ndimage\u001b[38;5;241m.\u001b[39mndim \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m3\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m ndimage\u001b[38;5;241m.\u001b[39mshape[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m] \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[0;32m--> 433\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCan\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mt write images with one color channel.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 434\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m ndimage\u001b[38;5;241m.\u001b[39mndim \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m3\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m ndimage\u001b[38;5;241m.\u001b[39mshape[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m] \u001b[38;5;129;01min\u001b[39;00m [\u001b[38;5;241m2\u001b[39m, \u001b[38;5;241m3\u001b[39m, \u001b[38;5;241m4\u001b[39m]:\n\u001b[1;32m 435\u001b[0m \u001b[38;5;66;03m# Note: this makes a channel-last assumption\u001b[39;00m\n\u001b[1;32m 436\u001b[0m is_batch \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n", | ||
"\u001b[0;31mValueError\u001b[0m: Can't write images with one color channel." | ||
] | ||
} | ||
], | ||
"source": [ | ||
"import imageio.v3 as iio\n", | ||
"from pathlib import Path\n", | ||
"import sleap_io as sio\n", | ||
"\n", | ||
"save_path = Path(\"minimal_instance.pkg.nwb_images\")\n", | ||
"try:\n", | ||
" save_path.mkdir(parents=True, exist_ok=True)\n", | ||
"except Exception as e:\n", | ||
" print(f\"An error {e} occurred. The directory could not be created.\")\n", | ||
"img_paths = []\n", | ||
"\n", | ||
"labels_original = sio.load_slp(\"tests/data/slp/minimal_instance.pkg.slp\")\n", | ||
"for i, lf in enumerate(labels_original):\n", | ||
" img_path = save_path / f\"img_{i}.png\"\n", | ||
" print(img_path)\n", | ||
" iio.imwrite(img_path, lf.image)\n", | ||
" img_paths.append(img_path)\n", | ||
"print(img_paths)" | ||
] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improve error handling for image writing. This cell attempts to write images, but fails due to an unsupported single color channel. This issue should be caught and handled, or the notebook should ensure that only supported image formats are processed. try:
for i, lf in enumerate(labels_original):
img_path = save_path / f"img_{i}.png"
print(img_path)
iio.imwrite(img_path, lf.image)
img_paths.append(img_path)
except ValueError as e:
print(f"Failed to write image: {e}") |
||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "io_dev", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.12.4" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the KeyError issue.
The code encounters a KeyError when attempting to save and load labels in NWB format. Verify the file path and format.
Committable suggestion