ethograph 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ethograph might be problematic. Click here for more details.

Files changed (216) hide show
  1. ethograph-0.1.3/.claude/settings.local.json +57 -0
  2. ethograph-0.1.3/.github/copilot-instructions.md +96 -0
  3. ethograph-0.1.3/.github/workflows/docs_build_and_deploy.yml +46 -0
  4. ethograph-0.1.3/.github/workflows/test_and_deploy.yml +61 -0
  5. ethograph-0.1.3/.gitignore +105 -0
  6. ethograph-0.1.3/.readthedocs.yaml +19 -0
  7. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/Activate.ps1 +247 -0
  8. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/activate +76 -0
  9. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/activate.bat +34 -0
  10. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/deactivate.bat +22 -0
  11. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/ethograph-gui.exe +0 -0
  12. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/ethograph.exe +0 -0
  13. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/f2py.exe +0 -0
  14. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/fonttools.exe +0 -0
  15. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/markdown-it.exe +0 -0
  16. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/numba +8 -0
  17. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/numpy-config.exe +0 -0
  18. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/pip.exe +0 -0
  19. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/pip3.12.exe +0 -0
  20. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/pip3.exe +0 -0
  21. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/pyftmerge.exe +0 -0
  22. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/pyftsubset.exe +0 -0
  23. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/pygmentize.exe +0 -0
  24. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/python.exe +0 -0
  25. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/pythonw.exe +0 -0
  26. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/tabulate.exe +0 -0
  27. ethograph-0.1.3/.tmp_pypi_smoke/Scripts/ttx.exe +0 -0
  28. ethograph-0.1.3/.tmp_pypi_smoke/pyvenv.cfg +5 -0
  29. ethograph-0.1.3/.tmp_pypi_smoke/share/man/man1/ttx.1 +225 -0
  30. ethograph-0.1.3/CLAUDE.md +338 -0
  31. ethograph-0.1.3/LICENSE +28 -0
  32. ethograph-0.1.3/MANIFEST.in +8 -0
  33. ethograph-0.1.3/PKG-INFO +92 -0
  34. ethograph-0.1.3/README.md +7 -0
  35. ethograph-0.1.3/configs/crowlab/ReadMe.md +1 -0
  36. ethograph-0.1.3/configs/crowlab/changepoint_settings_old.yaml +13 -0
  37. ethograph-0.1.3/configs/crowlab/mapping.txt +26 -0
  38. ethograph-0.1.3/configs/crowlab/mapping_Ivy.txt +21 -0
  39. ethograph-0.1.3/configs/crowlab/mapping_setup_audio.txt +8 -0
  40. ethograph-0.1.3/configs/crowlab/model/Crow1_inference_20260330_161224.json +79 -0
  41. ethograph-0.1.3/configs/crowlab/model/Crow1_inference_20260330_161259.json +80 -0
  42. ethograph-0.1.3/configs/crowlab/model/Freddy_inference_20260330_160621.json +57 -0
  43. ethograph-0.1.3/configs/crowlab/model/Freddy_train_20251021_164220.json +64 -0
  44. ethograph-0.1.3/configs/crowlab/model/Freddy_train_20251021_164220_epoch-100.model +0 -0
  45. ethograph-0.1.3/configs/crowlab/model/Ivy_CV_20260130_173800.json +111 -0
  46. ethograph-0.1.3/configs/crowlab/model/Ivy_inference_20260203_092442.json +73 -0
  47. ethograph-0.1.3/configs/crowlab/model/Ivy_inference_20260204_141527.json +70 -0
  48. ethograph-0.1.3/configs/crowlab/model/Ivy_inference_20260206_122331.json +80 -0
  49. ethograph-0.1.3/configs/crowlab/model/Ivy_train_20260202_191138_epoch-100.model +0 -0
  50. ethograph-0.1.3/configs/crowlab/model/Ivy_train_20260203_153754.json +70 -0
  51. ethograph-0.1.3/configs/crowlab/model/Poppy_inference_20260312_100707.json +76 -0
  52. ethograph-0.1.3/configs/crowlab/model/Poppy_inference_20260327_102414.json +78 -0
  53. ethograph-0.1.3/configs/crowlab/model/Poppy_inference_20260330_140808.json +78 -0
  54. ethograph-0.1.3/configs/crowlab/model/Poppy_inference_20260402_104151.json +79 -0
  55. ethograph-0.1.3/configs/crowlab/model/Poppy_train_20260326_190925.json +80 -0
  56. ethograph-0.1.3/configs/crowlab/model/Poppy_train_20260331_175332.json +80 -0
  57. ethograph-0.1.3/configs/crowlab/model/ReadMe - model Freddy_train_20251021_164220_epoch-100.txt +1 -0
  58. ethograph-0.1.3/configs/crowlab/space.yaml +33 -0
  59. ethograph-0.1.3/configs/model/Ivy_inference_20260415_093050.json +154 -0
  60. ethograph-0.1.3/configs/model/Ivy_inference_20260415_100537.json +154 -0
  61. ethograph-0.1.3/configs/model/Ivy_inference_20260415_101145.json +154 -0
  62. ethograph-0.1.3/configs/model/Ivy_inference_20260415_105230.json +155 -0
  63. ethograph-0.1.3/configs/model/Ivy_inference_20260415_172636.json +154 -0
  64. ethograph-0.1.3/configs/model/Ivy_inference_20260417_145159.json +154 -0
  65. ethograph-0.1.3/ethograph/__init__.py +115 -0
  66. ethograph-0.1.3/ethograph/__main__.py +3 -0
  67. ethograph-0.1.3/ethograph/assets/icon.ico +0 -0
  68. ethograph-0.1.3/ethograph/assets/icon.png +0 -0
  69. ethograph-0.1.3/ethograph/assets/menu.json +27 -0
  70. ethograph-0.1.3/ethograph/cli.py +71 -0
  71. ethograph-0.1.3/ethograph/crowlab/io_matlab.py +264 -0
  72. ethograph-0.1.3/ethograph/crowlab/legacy.py +389 -0
  73. ethograph-0.1.3/ethograph/datasets.py +314 -0
  74. ethograph-0.1.3/ethograph/features/__init__.py +0 -0
  75. ethograph-0.1.3/ethograph/features/audio_changepoints.py +176 -0
  76. ethograph-0.1.3/ethograph/features/changepoints.py +501 -0
  77. ethograph-0.1.3/ethograph/features/energy.py +389 -0
  78. ethograph-0.1.3/ethograph/features/movement.py +509 -0
  79. ethograph-0.1.3/ethograph/features/neural.py +219 -0
  80. ethograph-0.1.3/ethograph/features/oscillatory.py +55 -0
  81. ethograph-0.1.3/ethograph/features/preprocessing.py +184 -0
  82. ethograph-0.1.3/ethograph/gui/__init__.py +35 -0
  83. ethograph-0.1.3/ethograph/gui/app_constants.py +157 -0
  84. ethograph-0.1.3/ethograph/gui/app_state.py +1173 -0
  85. ethograph-0.1.3/ethograph/gui/audio_player.py +153 -0
  86. ethograph-0.1.3/ethograph/gui/dialog_busy_progress.py +119 -0
  87. ethograph-0.1.3/ethograph/gui/dialog_function_params.py +1065 -0
  88. ethograph-0.1.3/ethograph/gui/dialog_pose_video_matcher.py +289 -0
  89. ethograph-0.1.3/ethograph/gui/dialog_screen_recorder.py +419 -0
  90. ethograph-0.1.3/ethograph/gui/dialog_select_template.py +269 -0
  91. ethograph-0.1.3/ethograph/gui/dialog_video_downsample.py +292 -0
  92. ethograph-0.1.3/ethograph/gui/label_drawing_mixin.py +407 -0
  93. ethograph-0.1.3/ethograph/gui/make_pretty.py +290 -0
  94. ethograph-0.1.3/ethograph/gui/napari.yaml +12 -0
  95. ethograph-0.1.3/ethograph/gui/notify.py +56 -0
  96. ethograph-0.1.3/ethograph/gui/plots_audiotrace.py +208 -0
  97. ethograph-0.1.3/ethograph/gui/plots_base.py +416 -0
  98. ethograph-0.1.3/ethograph/gui/plots_container.py +1064 -0
  99. ethograph-0.1.3/ethograph/gui/plots_ephystrace.py +1687 -0
  100. ethograph-0.1.3/ethograph/gui/plots_heatmap.py +543 -0
  101. ethograph-0.1.3/ethograph/gui/plots_lineplot.py +412 -0
  102. ethograph-0.1.3/ethograph/gui/plots_overlay.py +316 -0
  103. ethograph-0.1.3/ethograph/gui/plots_psth.py +409 -0
  104. ethograph-0.1.3/ethograph/gui/plots_raster.py +283 -0
  105. ethograph-0.1.3/ethograph/gui/plots_space.py +942 -0
  106. ethograph-0.1.3/ethograph/gui/plots_spectrogram.py +323 -0
  107. ethograph-0.1.3/ethograph/gui/pose_render.py +664 -0
  108. ethograph-0.1.3/ethograph/gui/shortcuts.py +302 -0
  109. ethograph-0.1.3/ethograph/gui/templates/wizard_nwb_codegen.j2 +109 -0
  110. ethograph-0.1.3/ethograph/gui/video_manager.py +602 -0
  111. ethograph-0.1.3/ethograph/gui/video_sync.py +261 -0
  112. ethograph-0.1.3/ethograph/gui/widget_trials.py +444 -0
  113. ethograph-0.1.3/ethograph/gui/widgets_changepoints.py +1426 -0
  114. ethograph-0.1.3/ethograph/gui/widgets_data.py +2602 -0
  115. ethograph-0.1.3/ethograph/gui/widgets_ephys.py +2603 -0
  116. ethograph-0.1.3/ethograph/gui/widgets_help.py +257 -0
  117. ethograph-0.1.3/ethograph/gui/widgets_io.py +1765 -0
  118. ethograph-0.1.3/ethograph/gui/widgets_labels.py +1366 -0
  119. ethograph-0.1.3/ethograph/gui/widgets_meta.py +515 -0
  120. ethograph-0.1.3/ethograph/gui/widgets_navigation.py +947 -0
  121. ethograph-0.1.3/ethograph/gui/widgets_plot_settings.py +833 -0
  122. ethograph-0.1.3/ethograph/gui/widgets_psth.py +757 -0
  123. ethograph-0.1.3/ethograph/gui/widgets_transform.py +53 -0
  124. ethograph-0.1.3/ethograph/gui/wizard_boris.py +317 -0
  125. ethograph-0.1.3/ethograph/gui/wizard_media_files.py +1124 -0
  126. ethograph-0.1.3/ethograph/gui/wizard_multi_builder.py +186 -0
  127. ethograph-0.1.3/ethograph/gui/wizard_multi_codegen.py +231 -0
  128. ethograph-0.1.3/ethograph/gui/wizard_multi_tabs.py +1121 -0
  129. ethograph-0.1.3/ethograph/gui/wizard_multi_timeline.py +846 -0
  130. ethograph-0.1.3/ethograph/gui/wizard_multi_trials.py +564 -0
  131. ethograph-0.1.3/ethograph/gui/wizard_nwb.py +508 -0
  132. ethograph-0.1.3/ethograph/gui/wizard_overview.py +565 -0
  133. ethograph-0.1.3/ethograph/gui/wizard_single.py +1149 -0
  134. ethograph-0.1.3/ethograph/io/catalog.py +953 -0
  135. ethograph-0.1.3/ethograph/io/data_loader.py +670 -0
  136. ethograph-0.1.3/ethograph/io/dataset.py +282 -0
  137. ethograph-0.1.3/ethograph/io/metadata_table.py +279 -0
  138. ethograph-0.1.3/ethograph/io/nwb_alignment.py +1367 -0
  139. ethograph-0.1.3/ethograph/io/nwb_import.py +170 -0
  140. ethograph-0.1.3/ethograph/io/plot_sources.py +511 -0
  141. ethograph-0.1.3/ethograph/io/pynapple.py +226 -0
  142. ethograph-0.1.3/ethograph/io/time_model.py +512 -0
  143. ethograph-0.1.3/ethograph/io/time_sources.py +131 -0
  144. ethograph-0.1.3/ethograph/io/trialtree.py +572 -0
  145. ethograph-0.1.3/ethograph/io/validation.py +289 -0
  146. ethograph-0.1.3/ethograph/labels/__init__.py +11 -0
  147. ethograph-0.1.3/ethograph/labels/boris.py +323 -0
  148. ethograph-0.1.3/ethograph/labels/converters.py +425 -0
  149. ethograph-0.1.3/ethograph/labels/crowsetta_format.py +120 -0
  150. ethograph-0.1.3/ethograph/labels/export.py +145 -0
  151. ethograph-0.1.3/ethograph/labels/intervals.py +708 -0
  152. ethograph-0.1.3/ethograph/labels/ml.py +505 -0
  153. ethograph-0.1.3/ethograph/labels/plots.py +336 -0
  154. ethograph-0.1.3/ethograph/labels/predictions.py +257 -0
  155. ethograph-0.1.3/ethograph/labels/tsv_store.py +270 -0
  156. ethograph-0.1.3/ethograph/model/batch_gen.py +135 -0
  157. ethograph-0.1.3/ethograph/model/cetnet_encoder.py +589 -0
  158. ethograph-0.1.3/ethograph/model/dataset.py +302 -0
  159. ethograph-0.1.3/ethograph/model/eval_metrics.py +244 -0
  160. ethograph-0.1.3/ethograph/model/eval_plotting.py +465 -0
  161. ethograph-0.1.3/ethograph/shortcuts.py +126 -0
  162. ethograph-0.1.3/ethograph/utils/__init__.py +0 -0
  163. ethograph-0.1.3/ethograph/utils/arraytools.py +361 -0
  164. ethograph-0.1.3/ethograph/utils/audio.py +65 -0
  165. ethograph-0.1.3/ethograph/utils/download.py +625 -0
  166. ethograph-0.1.3/ethograph/utils/nwb.py +156 -0
  167. ethograph-0.1.3/ethograph/utils/paths.py +277 -0
  168. ethograph-0.1.3/ethograph/utils/qt.py +198 -0
  169. ethograph-0.1.3/ethograph/utils/sequences.py +129 -0
  170. ethograph-0.1.3/ethograph/utils/stream_durations.py +168 -0
  171. ethograph-0.1.3/ethograph/utils/xr_utils.py +165 -0
  172. ethograph-0.1.3/ethograph/video_features/base_extractor.py +122 -0
  173. ethograph-0.1.3/ethograph/video_features/checkpoint/S3D_kinetics400_torchified.pt +0 -0
  174. ethograph-0.1.3/ethograph/video_features/extract_s3d.py +117 -0
  175. ethograph-0.1.3/ethograph/video_features/s3d.py +357 -0
  176. ethograph-0.1.3/ethograph/video_features/s3d.yml +16 -0
  177. ethograph-0.1.3/ethograph/video_features/transforms.py +309 -0
  178. ethograph-0.1.3/ethograph/video_features/utils.py +168 -0
  179. ethograph-0.1.3/ethograph.egg-info/PKG-INFO +92 -0
  180. ethograph-0.1.3/ethograph.egg-info/SOURCES.txt +214 -0
  181. ethograph-0.1.3/ethograph.egg-info/dependency_links.txt +1 -0
  182. ethograph-0.1.3/ethograph.egg-info/entry_points.txt +8 -0
  183. ethograph-0.1.3/ethograph.egg-info/requires.txt +67 -0
  184. ethograph-0.1.3/ethograph.egg-info/top_level.txt +1 -0
  185. ethograph-0.1.3/examples/assets/birdpark0.png +0 -0
  186. ethograph-0.1.3/examples/assets/birdpark1.png +0 -0
  187. ethograph-0.1.3/examples/assets/canary.png +0 -0
  188. ethograph-0.1.3/examples/assets/cricket0.png +0 -0
  189. ethograph-0.1.3/examples/assets/cricket1.png +0 -0
  190. ethograph-0.1.3/examples/assets/cricket2.png +0 -0
  191. ethograph-0.1.3/examples/assets/lockbox1.png +0 -0
  192. ethograph-0.1.3/examples/assets/lockbox2.gif +0 -0
  193. ethograph-0.1.3/examples/assets/moll1.png +0 -0
  194. ethograph-0.1.3/examples/assets/moll2.png +0 -0
  195. ethograph-0.1.3/examples/convert_dataset_birdpark.ipynb +183 -0
  196. ethograph-0.1.3/examples/convert_dataset_pair24.ipynb +283 -0
  197. ethograph-0.1.3/examples/convert_datset_lockbox.ipynb +241 -0
  198. ethograph-0.1.3/examples/create_dataset_Moll25.ipynb +475 -0
  199. ethograph-0.1.3/examples/create_dataset_cricket.ipynb +204 -0
  200. ethograph-0.1.3/pyproject.toml +219 -0
  201. ethograph-0.1.3/scripts/DOCS_commands.md +88 -0
  202. ethograph-0.1.3/scripts/PUBLISHING.md +40 -0
  203. ethograph-0.1.3/scripts/community call.ipynb +79 -0
  204. ethograph-0.1.3/scripts/dandi_ibl-brainwide.ipynb.ipynb +68 -0
  205. ethograph-0.1.3/scripts/debug_gui.py +22 -0
  206. ethograph-0.1.3/scripts/debug_launch_copy_paste.json +21 -0
  207. ethograph-0.1.3/scripts/ethograph_alignment_setup_20260402_220508.ipynb +1697 -0
  208. ethograph-0.1.3/scripts/model/eval.ipynb +92 -0
  209. ethograph-0.1.3/scripts/model/find_best_s3d.ipynb +175 -0
  210. ethograph-0.1.3/scripts/model/model_config_Ivy.py +177 -0
  211. ethograph-0.1.3/scripts/model/model_config_Poppy.py +180 -0
  212. ethograph-0.1.3/scripts/model/model_run.py +320 -0
  213. ethograph-0.1.3/scripts/model/s3d_features.py +57 -0
  214. ethograph-0.1.3/scripts/nwb_video_testing.ipynb +2256 -0
  215. ethograph-0.1.3/setup.cfg +4 -0
  216. ethograph-0.1.3/todo.md +15 -0
@@ -0,0 +1,57 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(*)",
5
+ "WebSearch",
6
+ "WebFetch(*)",
7
+ "mcp__Ref__ref_search_documentation",
8
+ "mcp__Ref__ref_read_url",
9
+ "mcp__ide__getDiagnostics",
10
+ "mcp__ide__executeCode",
11
+ "WebFetch(domain:raw.githubusercontent.com)",
12
+ "Bash(grep -h \"^import\\\\|^from\" ethograph/gui/*.py)",
13
+ "Bash(find ethograph:*)",
14
+ "Bash(for pkg:*)",
15
+ "Bash(do echo:*)",
16
+ "Bash(grep -r \"^import $pkg\\\\|^from $pkg\" --include=\"*.py\")",
17
+ "Bash(done)",
18
+ "Bash(powershell -Command \"conda activate ethograph; pip install sphinx-design 2>&1 | Select-Object -Last 3\")",
19
+ "Bash(powershell -Command \"conda activate ethograph; sphinx-build -b html docs/source docs/_build/html 2>&1 | Select-Object -Last 30\")",
20
+ "Bash(powershell -Command \"conda activate ethograph; pip install sphinx-autodoc-typehints linkify-it-py nbsphinx sphinx-sitemap 2>&1 | Select-Object -Last 5\")",
21
+ "Bash(powershell -Command \"conda activate ethograph; pip install myst-parser 2>&1 | Select-Object -Last 3\")",
22
+ "Bash(powershell -Command \"conda activate ethograph; pip install pydata-sphinx-theme 2>&1 | Select-Object -Last 3\")",
23
+ "Bash(powershell -Command \"conda activate ethograph; sphinx-build -b html docs/source docs/_build/html 2>&1 | Select-String ''WARNING''\")",
24
+ "Bash(powershell -Command \"conda activate ethograph; sphinx-build -b html docs/source docs/_build/html 2>&1\"#)",
25
+ "Bash(powershell -Command \"conda activate ethograph; sphinx-build -W -b html docs/source docs/_build/html2 2>&1\")",
26
+ "Bash(powershell -Command \"conda activate ethograph; sphinx-build -W -b html docs/source docs/_build/html3 2>&1\")",
27
+ "Bash(powershell -Command \"conda activate ethograph; sphinx-build -b html docs/source docs/_build/html 2>&1\")",
28
+ "Bash(powershell -Command \"conda activate ethograph; pip install -e ''.[dev]'' 2>&1 | tail -15\")",
29
+ "Bash(powershell -Command \"conda activate ethograph; pip install build 2>&1 | tail -3\")",
30
+ "Bash(powershell -Command \"conda activate ethograph; python -m build 2>&1 | tail -10\")",
31
+ "Bash(powershell -Command \"conda activate ethograph; python -m zipfile -l dist/ethograph-0.1.dev1+gfbf9f7e5b.d20260328-py3-none-any.whl 2>&1\")",
32
+ "Bash(powershell -Command \"conda activate ethograph; python -c ''import ethograph as eto; print\\(eto.__version__\\); print\\(eto.TrialTree\\); dt = eto.TrialTree\\(\\); print\\(\"\"TrialTree OK\"\"\\)'' 2>&1\")",
33
+ "Bash(powershell -Command \"conda activate ethograph; python -c \"\"import ethograph as eto; print\\(eto.__version__\\); print\\(eto.TrialTree\\)\"\" 2>&1\")",
34
+ "Bash(powershell -Command \"conda activate ethograph2; pip install uv 2>&1 | tail -3\")",
35
+ "Bash(powershell -Command \"conda activate ethograph2; uv pip install -e ''''.[all]'''' 2>&1\")",
36
+ "Bash(powershell -Command \"conda activate ethograph; pip show vocalseg 2>&1\")",
37
+ "Bash(powershell -Command \"conda activate ethograph; pip show napari-pyav 2>&1\")",
38
+ "Bash(powershell -Command \"conda activate ethograph2; uv pip install napari-pyav 2>&1\")",
39
+ "Bash(powershell -Command \"conda activate ethograph2; python -c \"\"import ethograph as eto; print\\(eto.__version__\\); print\\(eto.TrialTree\\)\"\" 2>&1\")",
40
+ "Bash(powershell -Command \"conda activate ethograph2; pip show napari-pyav 2>&1\")",
41
+ "Bash(powershell -Command \"conda activate ethograph2; pip show audioio 2>&1\")",
42
+ "Bash(powershell -Command \"conda activate ethograph; python -m sphinx -b html docs/source docs/_build/html 2>&1\")",
43
+ "Bash(powershell -Command \"conda activate ethograph2; uv pip install sphinx pydata-sphinx-theme sphinx-autodoc-typehints sphinx-design sphinx-sitemap myst-parser nbsphinx linkify-it-py 2>&1\")",
44
+ "Bash(powershell -Command \"conda activate ethograph2; python -m sphinx -b html docs/source docs/_build/html 2>&1\")",
45
+ "Bash(powershell -Command \"conda activate ethograph2; python -c \"\"import movement; print\\(movement.__file__\\)\"\" 2>&1\")",
46
+ "Bash(cd:*)",
47
+ "Bash(powershell -Command \"conda activate ethograph2; uv pip install nbsphinx-link 2>&1\")",
48
+ "Bash(powershell -Command \"conda activate ethograph2; python -c \"\"import xarray; print\\(xarray.DataTree.__module__, xarray.DataTree.__name__\\)\"\" 2>&1\")"
49
+ ],
50
+ "deny": [
51
+ "Bash(rm:*)",
52
+ "Bash(del:*)",
53
+ "Bash(rmdir:*)",
54
+ "Bash(Remove-Item:*)"
55
+ ]
56
+ }
57
+ }
@@ -0,0 +1,96 @@
1
+ ## Frame Rate Guidelines
2
+
3
+ Never hardcode frame rates (e.g., 30 fps) anywhere in the codebase. Always use actual source metadata (e.g., video.fps, audio sample rate) or user settings. If a default is needed, make it configurable and document the rationale.
4
+
5
+ # CLAUDE.md
6
+
7
+ ## Continue
8
+
9
+ You always keep proposing things, and not implementing. Stop waiting for me to say 'yes go'.
10
+
11
+
12
+ ## System prompt
13
+
14
+ ---
15
+ name: python-pro
16
+ description: Write idiomatic Python code with advanced features like decorators, generators, and async/await. Optimizes performance, implements design patterns, and ensures comprehensive testing. Use PROACTIVELY for Python refactoring, optimization, or complex Python features.
17
+ ---
18
+
19
+ You are a Python expert specializing in clean, performant, and idiomatic Python code.
20
+
21
+ ## Focus Areas
22
+ - Advanced Python features (decorators, metaclasses, descriptors)
23
+ - Async/await and concurrent programming
24
+ - Performance optimization and profiling
25
+ - Design patterns and SOLID principles in Python
26
+ - SOLID stands for:
27
+ Single-responsibility principle (SRP)
28
+ Open-closed principle (OCP)
29
+ Liskov substitution principle (LSP)
30
+ Interface segregation principle (ISP)
31
+ Dependency inversion principle (DIP)
32
+ - Comprehensive testing (pytest, mocking, fixtures)
33
+ - Type hints and static analysis (mypy, ruff)
34
+
35
+ ## Approach
36
+ 1. Pythonic code - follow PEP 8 and Python idioms
37
+ 2. Prefer composition over inheritance
38
+ 3. Use generators for memory efficiency
39
+ 4. Comprehensive error handling with custom exceptions
40
+ 5. Test coverage above 90% with edge cases
41
+
42
+ ## Import statements
43
+
44
+ When modifying a Python file, always clean up the import statements at the top:
45
+ - Remove unused imports
46
+ - Add any missing imports needed by new code
47
+ - Sort imports: stdlib → third-party → local (following isort conventions)
48
+ - Use explicit imports rather than wildcard (`from x import *`)
49
+ - Never place import statements inside functions, methods, or any local scope. All imports belong at the top of the file, regardless of how rarely the code path is executed.
50
+ - E.g. never do the following. Only if this would avoid a circular import, that's the only exception.
51
+ def load_pose_from_file(...):
52
+ from movement.io import load_poses
53
+
54
+
55
+ ## Philosophy for adding comments
56
+ "Write code with the philosophy of self-documenting code, where the names of functions, variables, and the overall structure should make the purpose clear without the need for excessive comments. This follows the principle outlined by Robert C. Martin in 'Clean Code,' where the code itself expresses its intent. Therefore, comments should be used very sparingly and only when the code is not obvious, which should occur very, very rarely, as stated in 'The Pragmatic Programmer': 'Good code is its own best documentation. Comments are a failure to express yourself in code.'"
57
+
58
+ ## Error Handling: Fail Fast
59
+
60
+ Distinguish BUGS from RUNTIME CONDITIONS:
61
+ - BUG (wrong type, missing key, None where value expected) → Let it crash.
62
+ The developer needs the traceback.
63
+ - RUNTIME CONDITION (file not found, invalid user input, device disconnected)
64
+ → Handle gracefully.
65
+
66
+ Rules:
67
+ - Never wrap code in try/except that returns None or defaults when the
68
+ operation MUST succeed for correctness
69
+ - Never add `if x is not None` guards against your own code's output
70
+ - Catch broad exceptions ONLY at the outermost GUI boundary (to show
71
+ error dialogs, not to silently degrade)
72
+ - This codebase has defined data flow contracts — trust them, don't
73
+ defensively re-check upstream outputs
74
+
75
+ ## Output
76
+ - Clean Python code with type hints
77
+ - Unit tests with pytest and fixtures
78
+ - Performance benchmarks for critical paths
79
+ - Documentation with docstrings and examples
80
+ - Refactoring suggestions for existing code
81
+ - Memory and CPU profiling results when relevant
82
+
83
+ Leverage Python's standard library first. Use third-party packages judiciously.
84
+
85
+ ## Managing Claude.md
86
+
87
+ After making major design changes, change this claude.md file to match the current state of the repo.
88
+
89
+ ## Development Notes
90
+
91
+ Claude Code has permission to read make any necessary changes to files in this repository during development tasks.
92
+ It has also permissions to read (but not edit!) the folders:
93
+ C:\Users\Admin\Documents\Akseli\Code\ethograph
94
+ C:\Users\Admin\anaconda3\envs\ethograph-gui
95
+
96
+
@@ -0,0 +1,46 @@
1
+ name: Build Sphinx docs and deploy to GitHub Pages
2
+
3
+ # Generate the documentation on all merges to main, all pull requests, or by
4
+ # manual workflow dispatch. The build job can be used as a CI check that the
5
+ # docs still build successfully. The deploy job only runs when a tag is
6
+ # pushed and actually moves the generated html to the gh-pages branch
7
+ # (which triggers a GitHub pages deployment).
8
+ on:
9
+ push:
10
+ branches:
11
+ - main
12
+ tags:
13
+ - '*'
14
+ pull_request:
15
+ workflow_dispatch:
16
+
17
+
18
+ jobs:
19
+ linting:
20
+ # scheduled workflows should not run on forks
21
+ if: (${{ github.event_name == 'schedule' }} && ${{ github.repository_owner == 'neuroinformatics-unit' }} && ${{ github.ref == 'refs/heads/main' }}) || (${{ github.event_name != 'schedule' }})
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - uses: neuroinformatics-unit/actions/lint@v2
25
+
26
+ build_sphinx_docs:
27
+ name: Build Sphinx Docs
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - uses: neuroinformatics-unit/actions/build_sphinx_docs@v2
31
+ with:
32
+ python-version: '3.12'
33
+ check-links: false
34
+ use-make: true
35
+
36
+ deploy_sphinx_docs:
37
+ name: Deploy Sphinx Docs
38
+ needs: build_sphinx_docs
39
+ permissions:
40
+ contents: write
41
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
42
+ runs-on: ubuntu-latest
43
+ steps:
44
+ - uses: neuroinformatics-unit/actions/deploy_sphinx_docs@v2
45
+ with:
46
+ secret_input: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,61 @@
1
+ name: tests
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - '*'
7
+ tags:
8
+ - '*'
9
+ pull_request:
10
+
11
+ jobs:
12
+ linting:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: neuroinformatics-unit/actions/lint@v2
16
+
17
+ manifest:
18
+ name: Check Manifest
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: neuroinformatics-unit/actions/check_manifest@v2
22
+
23
+ test:
24
+ needs: [linting, manifest]
25
+ name: ${{ matrix.os }} py${{ matrix.python-version }}
26
+ runs-on: ${{ matrix.os }}
27
+ strategy:
28
+ matrix:
29
+ # Run all supported Python versions on linux
30
+ python-version: ["3.11", "3.12", "3.13"]
31
+ os: [ubuntu-latest]
32
+ # Include one windows and macos run
33
+ include:
34
+ - os: macos-latest
35
+ python-version: "3.13"
36
+ - os: windows-latest
37
+ python-version: "3.13"
38
+
39
+ steps:
40
+ # Run tests
41
+ - uses: neuroinformatics-unit/actions/test@v2
42
+ with:
43
+ python-version: ${{ matrix.python-version }}
44
+
45
+ build_sdist_wheels:
46
+ name: Build source distribution
47
+ needs: [test]
48
+ if: github.event_name == 'push' && github.ref_type == 'tag'
49
+ runs-on: ubuntu-latest
50
+ steps:
51
+ - uses: neuroinformatics-unit/actions/build_sdist_wheels@v2
52
+
53
+
54
+ upload_all:
55
+ name: Publish build distributions
56
+ needs: [build_sdist_wheels]
57
+ runs-on: ubuntu-latest
58
+ steps:
59
+ - uses: neuroinformatics-unit/actions/upload_pypi@v2
60
+ with:
61
+ secret-pypi-key: ${{ secrets.TWINE_API_KEY }}
@@ -0,0 +1,105 @@
1
+ data/
2
+ logging/
3
+ result/
4
+ configs/crowlab/model/
5
+ *.mp4
6
+ *.avi
7
+ *.mkv
8
+ *.mov
9
+ !docs/source/_static/videos/*.mp4
10
+ *.wav
11
+ *.nc
12
+ *.nwb
13
+ *.npy
14
+ *.csv
15
+ *.tsv
16
+ *.npz
17
+
18
+
19
+
20
+ # Byte-compiled / optimized / DLL files
21
+ __pycache__/
22
+ *.py[cod]
23
+ *$py.class
24
+
25
+ # C extensions
26
+ *.so
27
+
28
+ # Distribution / packaging
29
+ .Python
30
+ env/
31
+ build/
32
+ develop-eggs/
33
+ dist/
34
+ downloads/
35
+ eggs/
36
+ .eggs/
37
+ lib/
38
+ lib64/
39
+ parts/
40
+ sdist/
41
+ var/
42
+ *.egg-info/
43
+ .installed.cfg
44
+ *.egg
45
+
46
+ # PyInstaller
47
+ # Usually these files are written by a python script from a template
48
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
49
+ *.manifest
50
+ *.spec
51
+
52
+ # Installer logs
53
+ pip-log.txt
54
+ pip-delete-this-directory.txt
55
+
56
+ # Unit test / coverage reports
57
+ htmlcov/
58
+ .tox/
59
+ .coverage
60
+ .coverage.*
61
+ .cache
62
+ nosetests.xml
63
+ coverage.xml
64
+ *,cover
65
+ .hypothesis/
66
+
67
+ # Translations
68
+ *.mo
69
+ *.pot
70
+
71
+ # Django stuff:
72
+ *.log
73
+ local_settings.py
74
+
75
+ # Flask instance folder
76
+ instance/
77
+
78
+ # Sphinx documentation
79
+ docs/_build/
80
+
81
+ # MkDocs documentation
82
+ /site/
83
+
84
+ # PyBuilder
85
+ target/
86
+
87
+ # Pycharm and VSCode
88
+ .idea/
89
+ venv/
90
+ .vscode/
91
+
92
+ # IPython Notebook
93
+ .ipynb_checkpoints
94
+
95
+ # pyenv
96
+ .python-version
97
+
98
+ # OS
99
+ .DS_Store
100
+
101
+ # written by setuptools-scm
102
+ **/_version.py
103
+
104
+ # Development build artifacts
105
+ ethograph-*/
@@ -0,0 +1,19 @@
1
+ # Read the Docs configuration file
2
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html
3
+
4
+ version: 2
5
+
6
+ build:
7
+ os: ubuntu-22.04
8
+ tools:
9
+ python: "3.12"
10
+
11
+ sphinx:
12
+ configuration: docs/source/conf.py
13
+
14
+ python:
15
+ install:
16
+ - method: pip
17
+ path: .
18
+ extra_requirements:
19
+ - docs
@@ -0,0 +1,247 @@
1
+ <#
2
+ .Synopsis
3
+ Activate a Python virtual environment for the current PowerShell session.
4
+
5
+ .Description
6
+ Pushes the python executable for a virtual environment to the front of the
7
+ $Env:PATH environment variable and sets the prompt to signify that you are
8
+ in a Python virtual environment. Makes use of the command line switches as
9
+ well as the `pyvenv.cfg` file values present in the virtual environment.
10
+
11
+ .Parameter VenvDir
12
+ Path to the directory that contains the virtual environment to activate. The
13
+ default value for this is the parent of the directory that the Activate.ps1
14
+ script is located within.
15
+
16
+ .Parameter Prompt
17
+ The prompt prefix to display when this virtual environment is activated. By
18
+ default, this prompt is the name of the virtual environment folder (VenvDir)
19
+ surrounded by parentheses and followed by a single space (ie. '(.venv) ').
20
+
21
+ .Example
22
+ Activate.ps1
23
+ Activates the Python virtual environment that contains the Activate.ps1 script.
24
+
25
+ .Example
26
+ Activate.ps1 -Verbose
27
+ Activates the Python virtual environment that contains the Activate.ps1 script,
28
+ and shows extra information about the activation as it executes.
29
+
30
+ .Example
31
+ Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv
32
+ Activates the Python virtual environment located in the specified location.
33
+
34
+ .Example
35
+ Activate.ps1 -Prompt "MyPython"
36
+ Activates the Python virtual environment that contains the Activate.ps1 script,
37
+ and prefixes the current prompt with the specified string (surrounded in
38
+ parentheses) while the virtual environment is active.
39
+
40
+ .Notes
41
+ On Windows, it may be required to enable this Activate.ps1 script by setting the
42
+ execution policy for the user. You can do this by issuing the following PowerShell
43
+ command:
44
+
45
+ PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
46
+
47
+ For more information on Execution Policies:
48
+ https://go.microsoft.com/fwlink/?LinkID=135170
49
+
50
+ #>
51
+ Param(
52
+ [Parameter(Mandatory = $false)]
53
+ [String]
54
+ $VenvDir,
55
+ [Parameter(Mandatory = $false)]
56
+ [String]
57
+ $Prompt
58
+ )
59
+
60
+ <# Function declarations --------------------------------------------------- #>
61
+
62
+ <#
63
+ .Synopsis
64
+ Remove all shell session elements added by the Activate script, including the
65
+ addition of the virtual environment's Python executable from the beginning of
66
+ the PATH variable.
67
+
68
+ .Parameter NonDestructive
69
+ If present, do not remove this function from the global namespace for the
70
+ session.
71
+
72
+ #>
73
+ function global:deactivate ([switch]$NonDestructive) {
74
+ # Revert to original values
75
+
76
+ # The prior prompt:
77
+ if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) {
78
+ Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt
79
+ Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT
80
+ }
81
+
82
+ # The prior PYTHONHOME:
83
+ if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) {
84
+ Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME
85
+ Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME
86
+ }
87
+
88
+ # The prior PATH:
89
+ if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) {
90
+ Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH
91
+ Remove-Item -Path Env:_OLD_VIRTUAL_PATH
92
+ }
93
+
94
+ # Just remove the VIRTUAL_ENV altogether:
95
+ if (Test-Path -Path Env:VIRTUAL_ENV) {
96
+ Remove-Item -Path env:VIRTUAL_ENV
97
+ }
98
+
99
+ # Just remove VIRTUAL_ENV_PROMPT altogether.
100
+ if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) {
101
+ Remove-Item -Path env:VIRTUAL_ENV_PROMPT
102
+ }
103
+
104
+ # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether:
105
+ if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) {
106
+ Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force
107
+ }
108
+
109
+ # Leave deactivate function in the global namespace if requested:
110
+ if (-not $NonDestructive) {
111
+ Remove-Item -Path function:deactivate
112
+ }
113
+ }
114
+
115
+ <#
116
+ .Description
117
+ Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the
118
+ given folder, and returns them in a map.
119
+
120
+ For each line in the pyvenv.cfg file, if that line can be parsed into exactly
121
+ two strings separated by `=` (with any amount of whitespace surrounding the =)
122
+ then it is considered a `key = value` line. The left hand string is the key,
123
+ the right hand is the value.
124
+
125
+ If the value starts with a `'` or a `"` then the first and last character is
126
+ stripped from the value before being captured.
127
+
128
+ .Parameter ConfigDir
129
+ Path to the directory that contains the `pyvenv.cfg` file.
130
+ #>
131
+ function Get-PyVenvConfig(
132
+ [String]
133
+ $ConfigDir
134
+ ) {
135
+ Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg"
136
+
137
+ # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue).
138
+ $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue
139
+
140
+ # An empty map will be returned if no config file is found.
141
+ $pyvenvConfig = @{ }
142
+
143
+ if ($pyvenvConfigPath) {
144
+
145
+ Write-Verbose "File exists, parse `key = value` lines"
146
+ $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath
147
+
148
+ $pyvenvConfigContent | ForEach-Object {
149
+ $keyval = $PSItem -split "\s*=\s*", 2
150
+ if ($keyval[0] -and $keyval[1]) {
151
+ $val = $keyval[1]
152
+
153
+ # Remove extraneous quotations around a string value.
154
+ if ("'""".Contains($val.Substring(0, 1))) {
155
+ $val = $val.Substring(1, $val.Length - 2)
156
+ }
157
+
158
+ $pyvenvConfig[$keyval[0]] = $val
159
+ Write-Verbose "Adding Key: '$($keyval[0])'='$val'"
160
+ }
161
+ }
162
+ }
163
+ return $pyvenvConfig
164
+ }
165
+
166
+
167
+ <# Begin Activate script --------------------------------------------------- #>
168
+
169
+ # Determine the containing directory of this script
170
+ $VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
171
+ $VenvExecDir = Get-Item -Path $VenvExecPath
172
+
173
+ Write-Verbose "Activation script is located in path: '$VenvExecPath'"
174
+ Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)"
175
+ Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)"
176
+
177
+ # Set values required in priority: CmdLine, ConfigFile, Default
178
+ # First, get the location of the virtual environment, it might not be
179
+ # VenvExecDir if specified on the command line.
180
+ if ($VenvDir) {
181
+ Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values"
182
+ }
183
+ else {
184
+ Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir."
185
+ $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/")
186
+ Write-Verbose "VenvDir=$VenvDir"
187
+ }
188
+
189
+ # Next, read the `pyvenv.cfg` file to determine any required value such
190
+ # as `prompt`.
191
+ $pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir
192
+
193
+ # Next, set the prompt from the command line, or the config file, or
194
+ # just use the name of the virtual environment folder.
195
+ if ($Prompt) {
196
+ Write-Verbose "Prompt specified as argument, using '$Prompt'"
197
+ }
198
+ else {
199
+ Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value"
200
+ if ($pyvenvCfg -and $pyvenvCfg['prompt']) {
201
+ Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'"
202
+ $Prompt = $pyvenvCfg['prompt'];
203
+ }
204
+ else {
205
+ Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)"
206
+ Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'"
207
+ $Prompt = Split-Path -Path $venvDir -Leaf
208
+ }
209
+ }
210
+
211
+ Write-Verbose "Prompt = '$Prompt'"
212
+ Write-Verbose "VenvDir='$VenvDir'"
213
+
214
+ # Deactivate any currently active virtual environment, but leave the
215
+ # deactivate function in place.
216
+ deactivate -nondestructive
217
+
218
+ # Now set the environment variable VIRTUAL_ENV, used by many tools to determine
219
+ # that there is an activated venv.
220
+ $env:VIRTUAL_ENV = $VenvDir
221
+
222
+ if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
223
+
224
+ Write-Verbose "Setting prompt to '$Prompt'"
225
+
226
+ # Set the prompt to include the env name
227
+ # Make sure _OLD_VIRTUAL_PROMPT is global
228
+ function global:_OLD_VIRTUAL_PROMPT { "" }
229
+ Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT
230
+ New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt
231
+
232
+ function global:prompt {
233
+ Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) "
234
+ _OLD_VIRTUAL_PROMPT
235
+ }
236
+ $env:VIRTUAL_ENV_PROMPT = $Prompt
237
+ }
238
+
239
+ # Clear PYTHONHOME
240
+ if (Test-Path -Path Env:PYTHONHOME) {
241
+ Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME
242
+ Remove-Item -Path Env:PYTHONHOME
243
+ }
244
+
245
+ # Add the venv to the PATH
246
+ Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH
247
+ $Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH"