np-workflows 1.6.85__tar.gz → 1.6.90__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.
Files changed (90) hide show
  1. {np_workflows-1.6.85 → np_workflows-1.6.90}/PKG-INFO +6 -15
  2. np_workflows-1.6.90/pyproject.toml +199 -0
  3. np_workflows-1.6.90/setup.cfg +4 -0
  4. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/__init__.py +3 -5
  5. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/dynamic_routing/main.py +20 -41
  6. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/dynamic_routing/widgets.py +29 -24
  7. np_workflows-1.6.90/src/np_workflows/experiments/openscope_P3/P3_workflow_widget.py +75 -0
  8. np_workflows-1.6.90/src/np_workflows/experiments/openscope_P3/__init__.py +2 -0
  9. np_workflows-1.6.90/src/np_workflows/experiments/openscope_P3/main_P3_pilot.py +215 -0
  10. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/openscope_barcode/__init__.py +1 -1
  11. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/openscope_barcode/barcode_workflow_widget.py +14 -20
  12. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/openscope_barcode/camstim_scripts/barcode_mapping_script.py +8 -14
  13. np_workflows-1.6.90/src/np_workflows/experiments/openscope_barcode/camstim_scripts/barcode_opto_script.py +272 -0
  14. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/openscope_barcode/main_barcode_pilot.py +69 -69
  15. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/openscope_loop/__init__.py +1 -1
  16. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/openscope_loop/camstim_scripts/barcode_mapping_script.py +8 -14
  17. np_workflows-1.6.90/src/np_workflows/experiments/openscope_loop/camstim_scripts/barcode_opto_script.py +272 -0
  18. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/openscope_loop/loop_workflow_widget.py +11 -19
  19. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/openscope_loop/main_loop_pilot.py +66 -68
  20. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/openscope_psycode/__init__.py +1 -1
  21. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/openscope_psycode/main_psycode_pilot.py +69 -69
  22. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/openscope_psycode/psycode_workflow_widget.py +14 -20
  23. np_workflows-1.6.90/src/np_workflows/experiments/openscope_v2/__init__.py +2 -0
  24. np_workflows-1.6.90/src/np_workflows/experiments/openscope_v2/main_v2_pilot.py +215 -0
  25. np_workflows-1.6.90/src/np_workflows/experiments/openscope_v2/v2_workflow_widget.py +75 -0
  26. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/openscope_vippo/__init__.py +1 -1
  27. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/openscope_vippo/main_vippo_pilot.py +66 -68
  28. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/openscope_vippo/vippo_workflow_widget.py +14 -20
  29. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/task_trained_network/__init__.py +1 -1
  30. np_workflows-1.6.90/src/np_workflows/experiments/task_trained_network/camstim_scripts/make_tt_stims.py +33 -0
  31. np_workflows-1.6.90/src/np_workflows/experiments/task_trained_network/camstim_scripts/oct22_tt_stim_script.py +82 -0
  32. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/task_trained_network/camstim_scripts/ttn_main_script.py +19 -22
  33. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/task_trained_network/camstim_scripts/ttn_mapping_script.py +8 -14
  34. np_workflows-1.6.90/src/np_workflows/experiments/task_trained_network/camstim_scripts/ttn_opto_script.py +272 -0
  35. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/task_trained_network/main_ttn_pilot.py +73 -68
  36. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/task_trained_network/ttn_session_widget.py +11 -19
  37. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/task_trained_network/ttn_stim_config.py +23 -19
  38. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/templeton/main.py +18 -41
  39. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/templeton/widgets.py +26 -23
  40. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/shared/__init__.py +1 -1
  41. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/shared/base_experiments.py +442 -304
  42. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/shared/npxc.py +85 -53
  43. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/shared/widgets.py +374 -224
  44. np_workflows-1.6.90/src/np_workflows.egg-info/PKG-INFO +76 -0
  45. np_workflows-1.6.90/src/np_workflows.egg-info/SOURCES.txt +51 -0
  46. np_workflows-1.6.90/src/np_workflows.egg-info/dependency_links.txt +1 -0
  47. np_workflows-1.6.90/src/np_workflows.egg-info/entry_points.txt +2 -0
  48. np_workflows-1.6.90/src/np_workflows.egg-info/requires.txt +17 -0
  49. np_workflows-1.6.90/src/np_workflows.egg-info/top_level.txt +1 -0
  50. np_workflows-1.6.85/pyproject.toml +0 -145
  51. np_workflows-1.6.85/src/np_workflows/assets/images/logo_np_hab.png +0 -0
  52. np_workflows-1.6.85/src/np_workflows/assets/images/logo_np_vis.png +0 -0
  53. np_workflows-1.6.85/src/np_workflows/experiments/openscope_barcode/camstim_scripts/barcode_opto_script.py +0 -219
  54. np_workflows-1.6.85/src/np_workflows/experiments/openscope_loop/camstim_scripts/barcode_opto_script.py +0 -219
  55. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/make_tt_stims.py +0 -23
  56. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/oct22_tt_stim_script.py +0 -69
  57. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_00.stim +0 -5
  58. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_01.stim +0 -5
  59. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_02.stim +0 -5
  60. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_03.stim +0 -5
  61. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_04.stim +0 -5
  62. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_05.stim +0 -5
  63. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_06.stim +0 -5
  64. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_07.stim +0 -5
  65. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_08.stim +0 -5
  66. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_09.stim +0 -5
  67. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_10.stim +0 -5
  68. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_11.stim +0 -5
  69. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_12.stim +0 -5
  70. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_13.stim +0 -5
  71. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_14.stim +0 -5
  72. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_15.stim +0 -5
  73. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_16.stim +0 -5
  74. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_17.stim +0 -5
  75. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_18.stim +0 -5
  76. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/flash_250ms.stim +0 -20
  77. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/gabor_20_deg_250ms.stim +0 -30
  78. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/old_stim.stim +0 -5
  79. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/shuffle_reversed.stim +0 -5
  80. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/shuffle_reversed_1st.stim +0 -5
  81. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/stims/shuffle_reversed_2nd.stim +0 -5
  82. np_workflows-1.6.85/src/np_workflows/experiments/task_trained_network/camstim_scripts/ttn_opto_script.py +0 -219
  83. np_workflows-1.6.85/src/np_workflows/shared/camstim_scripts/flash_250ms.stim +0 -20
  84. np_workflows-1.6.85/src/np_workflows/shared/camstim_scripts/gabor_20_deg_250ms.stim +0 -30
  85. np_workflows-1.6.85/tests/model_sandbox.py +0 -20
  86. np_workflows-1.6.85/tests/widget_sandbox.ipynb +0 -2787
  87. {np_workflows-1.6.85 → np_workflows-1.6.90}/README.md +0 -0
  88. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/__init__.py +0 -0
  89. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/dynamic_routing/__init__.py +0 -0
  90. {np_workflows-1.6.85 → np_workflows-1.6.90}/src/np_workflows/experiments/templeton/__init__.py +0 -0
@@ -1,17 +1,18 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: np-workflows
3
- Version: 1.6.85
3
+ Version: 1.6.90
4
4
  Summary: Ecephys and behavior workflows for the Mindscope Neuropixels team.
5
- Author-Email: Ben Hardcastle <ben.hardcastle@alleninstitute.org>
5
+ Author-email: Ben Hardcastle <ben.hardcastle@alleninstitute.org>
6
6
  License: MIT
7
+ Project-URL: Repository, https://github.com/AllenInstitute/np_workflows
8
+ Project-URL: Issues, https://github.com/AllenInstitute/np_workflows/issues
7
9
  Classifier: Programming Language :: Python :: 3
8
10
  Classifier: Programming Language :: Python :: 3.11
9
11
  Classifier: License :: OSI Approved :: MIT License
10
12
  Classifier: Operating System :: Microsoft :: Windows
11
13
  Classifier: Operating System :: POSIX :: Linux
12
- Project-URL: Repository, https://github.com/AllenInstitute/np_workflows
13
- Project-URL: Issues, https://github.com/AllenInstitute/np_workflows/issues
14
14
  Requires-Python: ==3.11.*
15
+ Description-Content-Type: text/markdown
15
16
  Requires-Dist: np-services>=0.1.69
16
17
  Requires-Dist: np-session>=0.6.48
17
18
  Requires-Dist: np-config>=0.4.33
@@ -29,16 +30,6 @@ Requires-Dist: np-codeocean[dynamic-routing-metadata]>=0.2.1
29
30
  Requires-Dist: panel>=1.4.5
30
31
  Requires-Dist: aind-session>=0.1.20
31
32
  Requires-Dist: jupyter-bokeh>=4.0.5
32
- Provides-Extra: dev
33
- Requires-Dist: blue>=0.9.1; extra == "dev"
34
- Requires-Dist: pytest>=7.2.2; extra == "dev"
35
- Requires-Dist: mypy>=1.1.1; extra == "dev"
36
- Requires-Dist: coverage[toml]>=7.2.2; extra == "dev"
37
- Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
38
- Requires-Dist: bump>=1.3.2; extra == "dev"
39
- Requires-Dist: types-backports>=0.1.3; extra == "dev"
40
- Requires-Dist: ruff>=0.0.260; extra == "dev"
41
- Description-Content-Type: text/markdown
42
33
 
43
34
  # np_workflows
44
35
 
@@ -0,0 +1,199 @@
1
+ [project]
2
+ name = "np-workflows"
3
+ version = "1.6.90"
4
+ description = "Ecephys and behavior workflows for the Mindscope Neuropixels team."
5
+ authors = [
6
+ { name = "Ben Hardcastle", email = "ben.hardcastle@alleninstitute.org" },
7
+ ]
8
+ readme = "README.md"
9
+ requires-python = "==3.11.*"
10
+ dependencies = [
11
+ "np-services>=0.1.69",
12
+ "np-session>=0.6.48",
13
+ "np-config>=0.4.33",
14
+ "ipywidgets>=7",
15
+ "pydantic>=2",
16
+ "jupyterlab >= 3.6",
17
+ "ipylab >= 0.6.0",
18
+ "np-tools>=0.1.24",
19
+ "np-jobs>=0.0.3",
20
+ "universal-pathlib>=0.1.0",
21
+ "s3fs>=2023.6.0",
22
+ "npc-shields>=0.1.10",
23
+ "npc-sessions>=0.0.225",
24
+ "np-codeocean[dynamic-routing-metadata]>=0.2.1",
25
+ "panel>=1.4.5",
26
+ "aind-session>=0.1.20",
27
+ "jupyter-bokeh>=4.0.5",
28
+ ]
29
+ classifiers = [
30
+ "Programming Language :: Python :: 3",
31
+ "Programming Language :: Python :: 3.11",
32
+ "License :: OSI Approved :: MIT License",
33
+ "Operating System :: Microsoft :: Windows",
34
+ "Operating System :: POSIX :: Linux",
35
+ ]
36
+
37
+ [project.license]
38
+ text = "MIT"
39
+
40
+ [project.urls]
41
+ Repository = "https://github.com/AllenInstitute/np_workflows"
42
+ Issues = "https://github.com/AllenInstitute/np_workflows/issues"
43
+
44
+
45
+ [build-system]
46
+ requires = ["setuptools>=61", "wheel"]
47
+ build-backend = "setuptools.build_meta"
48
+
49
+ [project.scripts]
50
+ task = "poethepoet:main"
51
+
52
+ [dependency-groups]
53
+ task_runner = ["poethepoet>=0.33.1"]
54
+ linting = ["black>=25.1.0", "isort>=6.0.1", "ruff>=0.11.2"]
55
+ testing = ["pytest>=7.4.0", "mypy>=1.4.1", "pytest-cov>=4.1.0"]
56
+ bump = [
57
+ "bump-my-version>=1.1.1",
58
+ "git-changelog>=2.5.3",
59
+ ]
60
+ pynwb = [
61
+ "hdmf-zarr==0.11.0",
62
+ "pynwb==3.0.0",
63
+ ]
64
+
65
+ [tool.uv]
66
+ package = true
67
+ default-groups = "all"
68
+
69
+ [tool.bumpversion]
70
+ tag = true
71
+ allow_dirty = true
72
+ commit = true
73
+ commit_args = "-a"
74
+ message = "Bump version: {current_version} → {new_version} [skip actions]"
75
+ pre_commit_hooks = [
76
+ "uv lock --upgrade-package np_workflows",
77
+ "git-changelog -o CHANGELOG.md",
78
+ "uv build",
79
+ "uv publish",
80
+ ]
81
+ post_commit_hooks = [
82
+ "git push origin main",
83
+ "git push --tags",
84
+ ]
85
+
86
+ [tool.poe.tasks]
87
+ mypy = "mypy src --install-types --non-interactive"
88
+ pytest = "pytest --cov-report term-missing:skip-covered --cov-report=html"
89
+ test = ["pytest"]
90
+ ruff = "ruff check src --fix-only"
91
+ black = "black src"
92
+ format = ["ruff", "black"]
93
+ bump_pub_tag = "bump-my-version bump patch"
94
+ release = ["format", "bump_pub_tag"]
95
+
96
+ [tool.setuptools.packages.find]
97
+ where = ["src"]
98
+
99
+ [tool.setuptools.package-data]
100
+ np_workflows = ["py.typed"]
101
+
102
+ [tool.setuptools]
103
+ license-files = ["LICENSE"]
104
+
105
+ [tool.black]
106
+ # line-length = 100
107
+ target-version = ["py39", "py310", "py311"]
108
+
109
+ [tool.ruff]
110
+ line-length = 100
111
+ select = [
112
+ "B", # flake8-bugbear
113
+ "C4", # flake8-comprehensions
114
+ "E", # pycodestyle
115
+ "F", # pyflakes
116
+ "PGH", # pygrep-hooks
117
+ "RUF", # ruff
118
+ "W", # pycodestyle
119
+ "YTT", # flake8-2020
120
+ "ANN",
121
+ "C",
122
+ "I",
123
+ "RUF100",
124
+ "N",
125
+ "UP",
126
+ ]
127
+ # extend-ignore = ["B018", "B019"]
128
+ src = ["src"]
129
+ extend-exclude = ["tests/fixtures"]
130
+ target-version = "py39"
131
+
132
+ [tool.ruff.flake8-tidy-imports]
133
+ ban-relative-imports = "all"
134
+
135
+ [tool.ruff.mccabe]
136
+ max-complexity = 10
137
+
138
+ [tool.ruff.isort]
139
+ known-first-party = ["np_workflows"]
140
+
141
+ [tool.coverage.paths]
142
+ source = ["src"]
143
+
144
+ [tool.coverage.run]
145
+ branch = true
146
+ source = ["src"]
147
+
148
+ [tool.coverage.report]
149
+ skip_covered = true
150
+ show_missing = true
151
+ skip_empty = true
152
+ exclude_also = [
153
+ "raise AssertionError",
154
+ "raise NotImplementedError",
155
+ "if __name__ == .__main__.:",
156
+ "@(abc.)?abstractmethod",
157
+ "@typing.runtime_checkable",
158
+ ]
159
+
160
+ [tool.pytest.ini_options]
161
+ addopts = [
162
+ "--import-mode=importlib",
163
+ # "--doctest-modules",
164
+ "--ignore-glob=*scripts*,*examples*,*docs*",
165
+ "--cov",
166
+ "--cov-report=html",
167
+ "--cov-config=pyproject.toml",
168
+ "--doctest-glob=*README.md",
169
+ "-x",
170
+ # "-n=auto", for use with pytest-xdist
171
+ ]
172
+ doctest_optionflags = [
173
+ "NORMALIZE_WHITESPACE",
174
+ "IGNORE_EXCEPTION_DETAIL",
175
+ "ELLIPSIS",
176
+ ]
177
+ testpaths = ["src", "tests"]
178
+
179
+ [tool.mypy]
180
+ check_untyped_defs = false
181
+ disallow_untyped_defs = false
182
+ disallow_incomplete_defs = false
183
+ disallow_untyped_decorators = false
184
+ disallow_any_unimported = false
185
+ warn_return_any = false
186
+ warn_unused_ignores = true
187
+ no_implicit_optional = true
188
+ show_error_codes = true
189
+ ignore_missing_imports = true
190
+ implicit_reexport = false
191
+ exclude = ["src/np_workflows/scripts"]
192
+
193
+ [tool.isort]
194
+ profile = "black"
195
+ atomic = true
196
+ skip_glob = ["*/setup.py"]
197
+ filter_files = true
198
+ known_first_party = ["np_workflows"]
199
+
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -1,7 +1,5 @@
1
+ import np_workflows.experiments as experiments
2
+ import np_workflows.shared.base_experiments as base_experiments
1
3
  import np_workflows.shared.npxc as npxc
2
4
  import np_workflows.shared.widgets as widgets
3
- import np_workflows.shared.base_experiments as base_experiments
4
-
5
- import np_workflows.experiments as experiments
6
-
7
- from np_workflows.shared import *
5
+ from np_workflows.shared import *
@@ -1,48 +1,21 @@
1
1
  from __future__ import annotations
2
2
 
3
- import configparser
4
- import contextlib
5
- import copy
6
- import dataclasses
7
- import datetime
8
- import enum
9
- import functools
10
- import pathlib
11
- import platform
12
- import shutil
13
- import threading
14
- import time
15
- import zlib
16
- from typing import ClassVar, Literal, NamedTuple, NoReturn, Optional, Type, TypedDict
17
-
18
- import IPython
19
- import IPython.display
20
- import ipywidgets as ipw
21
- import np_config
22
3
  import np_logging
23
- import np_services
24
4
  import np_session
25
- import np_workflows
26
- import fabric
27
- import PIL.Image
28
- import pydantic
29
- from pyparsing import Any
30
5
  from np_services import (
31
- Service,
32
- Finalizable,
33
- ScriptCamstim,
6
+ MouseDirector,
7
+ NewScaleCoordinateRecorder,
34
8
  OpenEphys,
9
+ ScriptCamstim,
35
10
  Sync,
36
- ImageMVR,
37
11
  VideoMVR,
38
- NewScaleCoordinateRecorder,
39
- MouseDirector,
40
12
  )
41
13
 
42
14
  from np_workflows.shared import base_experiments
43
15
 
44
16
  logger = np_logging.getLogger(__name__)
45
17
 
18
+
46
19
  def new_experiment(
47
20
  mouse: int | str | np_session.Mouse,
48
21
  user: str | np_session.User,
@@ -50,29 +23,33 @@ def new_experiment(
50
23
  ) -> DRTask:
51
24
  """Create a new experiment for the given mouse and user."""
52
25
  experiment: DRTask
53
- if any(tag in workflow.name for tag in ('EPHYS', 'PRETEST')):
26
+ if any(tag in workflow.name for tag in ("EPHYS", "PRETEST")):
54
27
  experiment = Ephys(mouse, user)
55
- elif 'HAB' in workflow.name:
28
+ elif "HAB" in workflow.name:
56
29
  experiment = Hab(mouse, user)
57
- elif 'OPTO' in workflow.name:
30
+ elif "OPTO" in workflow.name:
58
31
  experiment = Opto(mouse, user)
59
- elif 'TRAINING' in workflow.name:
32
+ elif "TRAINING" in workflow.name:
60
33
  experiment = Training(mouse, user)
61
34
  else:
62
- raise ValueError(f"Unknown {workflow = }. Create an experiment with e.g.\n\n\texperiment = Ephys(mouse, user)\nexperiment.session.npexp_path.mkdir()")
35
+ raise ValueError(
36
+ f"Unknown {workflow = }. Create an experiment with e.g.\n\n\texperiment = Ephys(mouse, user)\nexperiment.session.npexp_path.mkdir()"
37
+ )
63
38
  experiment.workflow = workflow
64
39
  experiment.log(f"{experiment} created")
65
- experiment.session.npexp_path.mkdir(parents=True, exist_ok=True)
40
+ experiment.session.npexp_path.mkdir(parents=True, exist_ok=True)
66
41
  return experiment
67
42
 
43
+
68
44
  class DRTask(base_experiments.DynamicRoutingExperiment):
69
45
  """Provides project-specific methods and attributes, mainly related to camstim scripts."""
70
-
46
+
71
47
  default_session_subclass = np_session.DRPilotSession
72
-
48
+
73
49
  workflow: base_experiments.DynamicRoutingExperiment.Workflow
74
50
  """Enum for workflow type, e.g. PRETEST, HAB_AUD, HAB_VIS, EPHYS_ etc."""
75
51
 
52
+
76
53
  class Hab(DRTask):
77
54
  def __init__(self, *args, **kwargs):
78
55
  self.services = (
@@ -82,7 +59,8 @@ class Hab(DRTask):
82
59
  ScriptCamstim,
83
60
  )
84
61
  super().__init__(*args, **kwargs)
85
-
62
+
63
+
86
64
  class Opto(DRTask):
87
65
  def __init__(self, *args, **kwargs):
88
66
  self.services = (
@@ -106,6 +84,7 @@ class Ephys(DRTask):
106
84
  )
107
85
  super().__init__(*args, **kwargs)
108
86
 
87
+
109
88
  class Training(DRTask):
110
89
  def __init__(self, *args, **kwargs):
111
90
  self.services = (
@@ -114,4 +93,4 @@ class Training(DRTask):
114
93
  VideoMVR,
115
94
  ScriptCamstim,
116
95
  )
117
- super().__init__(*args, **kwargs)
96
+ super().__init__(*args, **kwargs)
@@ -1,29 +1,22 @@
1
- import configparser
2
- import contextlib
3
- import copy
4
- import enum
5
- import functools
6
- from typing import ClassVar, Literal, NamedTuple, NoReturn, Optional, TypedDict
7
-
8
1
  import IPython.display
9
2
  import ipywidgets as ipw
10
- import np_config
11
- import np_logging
12
3
  import np_session
13
- import np_workflows
14
- from pyparsing import Any
15
4
 
16
- from np_workflows.experiments.dynamic_routing.main import Ephys, Hab, DRTask
17
5
  from np_workflows.shared.base_experiments import DynamicRoutingExperiment
18
6
 
19
-
20
7
  # for widget, before creating a experiment --------------------------------------------- #
21
8
 
22
9
 
23
10
  class SelectedWorkflow:
24
- def __init__(self, workflow: str | DynamicRoutingExperiment.Workflow, mouse: str | int | np_session.Mouse):
11
+ def __init__(
12
+ self,
13
+ workflow: str | DynamicRoutingExperiment.Workflow,
14
+ mouse: str | int | np_session.Mouse,
15
+ ):
25
16
  if isinstance(workflow, str):
26
- workflow = DynamicRoutingExperiment.Workflow[workflow] # uses enum name (not value)
17
+ workflow = DynamicRoutingExperiment.Workflow[
18
+ workflow
19
+ ] # uses enum name (not value)
27
20
  self.workflow = workflow
28
21
  self.mouse = str(mouse)
29
22
 
@@ -55,8 +48,12 @@ def workflow_select_widget(
55
48
  )
56
49
  console = ipw.Output()
57
50
  with console:
58
- if last_workflow := np_session.Mouse(selection.mouse).state.get('last_workflow'):
59
- print(f"{mouse} last workflow: {last_workflow}\t({np_session.Mouse(selection.mouse).state.get('last_session')})")
51
+ if last_workflow := np_session.Mouse(selection.mouse).state.get(
52
+ "last_workflow"
53
+ ):
54
+ print(
55
+ f"{mouse} last workflow: {last_workflow}\t({np_session.Mouse(selection.mouse).state.get('last_session')})"
56
+ )
60
57
  print(f"Selected: {selection.workflow.name}")
61
58
 
62
59
  def update(change):
@@ -68,15 +65,23 @@ def workflow_select_widget(
68
65
  return
69
66
  if change["new"] == change["old"]:
70
67
  return
71
- selection.__init__(str(workflow_dropdown.value), mouse.id if isinstance(mouse, np_session.Mouse) else str(mouse))
68
+ selection.__init__(
69
+ str(workflow_dropdown.value),
70
+ mouse.id if isinstance(mouse, np_session.Mouse) else str(mouse),
71
+ )
72
72
  with console:
73
73
  print(f"Selected: {selection.workflow}")
74
- workflow_dropdown.observe(update, names='value')
75
74
 
76
- IPython.display.display(ipw.VBox([ipw.HBox([workflow_dropdown, workflow_descriptions]), console]))
75
+ workflow_dropdown.observe(update, names="value")
76
+
77
+ IPython.display.display(
78
+ ipw.VBox([ipw.HBox([workflow_dropdown, workflow_descriptions]), console])
79
+ )
77
80
 
78
81
  return selection
79
-
80
-
81
- def photodoc_widget(session: np_session.Session, reminder: str) -> None:
82
- print(f'Take an image in Vimba Viewer and save as:\n{session.npexp_path.name}_{reminder}.png')
82
+
83
+
84
+ def photodoc_widget(session: np_session.Session, reminder: str) -> None:
85
+ print(
86
+ f"Take an image in Vimba Viewer and save as:\n{session.npexp_path.name}_{reminder}.png"
87
+ )
@@ -0,0 +1,75 @@
1
+ import IPython.display
2
+ import ipywidgets as ipw
3
+ import np_session
4
+
5
+ from np_workflows.experiments.openscope_P3.main_P3_pilot import P3Session
6
+
7
+ global_state = {}
8
+ """Global variable for persisting widget states."""
9
+
10
+ # for widget, before creating a experiment --------------------------------------------- #
11
+
12
+
13
+ class SelectedSession:
14
+ def __init__(self, session: str | P3Session, mouse: str | int | np_session.Mouse):
15
+ if isinstance(session, str):
16
+ session = P3Session(session)
17
+ self.session = session
18
+ self.mouse = str(mouse)
19
+
20
+ def __repr__(self) -> str:
21
+ return f"{self.__class__.__name__}({self.session}, {self.mouse})"
22
+
23
+
24
+ def P3_workflow_widget(
25
+ mouse: str | int | np_session.Mouse,
26
+ ) -> SelectedSession:
27
+ """Select a stimulus session (hab, pretest, ephys) to run.
28
+
29
+ An object with mutable attributes is returned, so the selected session can be
30
+ updated along with the GUI selection. (Preference would be to return an enum
31
+ directly, and change it's value, but that doesn't seem possible.)
32
+
33
+ """
34
+
35
+ selection = SelectedSession(P3Session.PRETEST, mouse)
36
+
37
+ session_dropdown = ipw.Select(
38
+ options=tuple(_.value for _ in P3Session),
39
+ description="Session",
40
+ )
41
+
42
+ def update_selection():
43
+ selection.__init__(str(session_dropdown.value), str(mouse))
44
+
45
+ if previously_selected_value := global_state.get("selected_session"):
46
+ session_dropdown.value = previously_selected_value
47
+ update_selection()
48
+
49
+ console = ipw.Output()
50
+ with console:
51
+ if last_session := np_session.Mouse(selection.mouse).state.get(
52
+ "last_P3_session"
53
+ ):
54
+ print(f"{mouse} last session: {last_session}")
55
+ print(f"Selected: {selection.session}")
56
+
57
+ def update(change):
58
+ if change["name"] != "value":
59
+ return
60
+ if (options := getattr(change["owner"], "options", None)) and change[
61
+ "new"
62
+ ] not in options:
63
+ return
64
+ if change["new"] == change["old"]:
65
+ return
66
+ update_selection()
67
+ with console:
68
+ print(f"Selected: {selection.session}")
69
+ global_state["selected_session"] = selection.session.value
70
+
71
+ session_dropdown.observe(update, names="value")
72
+
73
+ IPython.display.display(ipw.VBox([session_dropdown, console]))
74
+
75
+ return selection
@@ -0,0 +1,2 @@
1
+ from .main_P3_pilot import Ephys, Hab, new_experiment, validate_selected_workflow
2
+ from .P3_workflow_widget import P3_workflow_widget