np-workflows 1.6.89__py3-none-any.whl → 1.6.90__py3-none-any.whl
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.
- np_workflows/__init__.py +3 -5
- np_workflows/experiments/dynamic_routing/main.py +20 -41
- np_workflows/experiments/dynamic_routing/widgets.py +29 -24
- np_workflows/experiments/openscope_P3/P3_workflow_widget.py +11 -19
- np_workflows/experiments/openscope_P3/__init__.py +1 -1
- np_workflows/experiments/openscope_P3/main_P3_pilot.py +66 -68
- np_workflows/experiments/openscope_barcode/__init__.py +1 -1
- np_workflows/experiments/openscope_barcode/barcode_workflow_widget.py +14 -20
- np_workflows/experiments/openscope_barcode/camstim_scripts/barcode_mapping_script.py +8 -14
- np_workflows/experiments/openscope_barcode/camstim_scripts/barcode_opto_script.py +121 -68
- np_workflows/experiments/openscope_barcode/main_barcode_pilot.py +69 -69
- np_workflows/experiments/openscope_loop/__init__.py +1 -1
- np_workflows/experiments/openscope_loop/camstim_scripts/barcode_mapping_script.py +8 -14
- np_workflows/experiments/openscope_loop/camstim_scripts/barcode_opto_script.py +121 -68
- np_workflows/experiments/openscope_loop/loop_workflow_widget.py +11 -19
- np_workflows/experiments/openscope_loop/main_loop_pilot.py +66 -68
- np_workflows/experiments/openscope_psycode/__init__.py +1 -1
- np_workflows/experiments/openscope_psycode/main_psycode_pilot.py +69 -69
- np_workflows/experiments/openscope_psycode/psycode_workflow_widget.py +14 -20
- np_workflows/experiments/openscope_v2/__init__.py +1 -1
- np_workflows/experiments/openscope_v2/main_v2_pilot.py +66 -68
- np_workflows/experiments/openscope_v2/v2_workflow_widget.py +11 -19
- np_workflows/experiments/openscope_vippo/__init__.py +1 -1
- np_workflows/experiments/openscope_vippo/main_vippo_pilot.py +66 -68
- np_workflows/experiments/openscope_vippo/vippo_workflow_widget.py +14 -20
- np_workflows/experiments/task_trained_network/__init__.py +1 -1
- np_workflows/experiments/task_trained_network/camstim_scripts/make_tt_stims.py +24 -14
- np_workflows/experiments/task_trained_network/camstim_scripts/oct22_tt_stim_script.py +54 -41
- np_workflows/experiments/task_trained_network/camstim_scripts/ttn_main_script.py +19 -22
- np_workflows/experiments/task_trained_network/camstim_scripts/ttn_mapping_script.py +8 -14
- np_workflows/experiments/task_trained_network/camstim_scripts/ttn_opto_script.py +121 -68
- np_workflows/experiments/task_trained_network/main_ttn_pilot.py +73 -68
- np_workflows/experiments/task_trained_network/ttn_session_widget.py +11 -19
- np_workflows/experiments/task_trained_network/ttn_stim_config.py +23 -19
- np_workflows/experiments/templeton/main.py +18 -41
- np_workflows/experiments/templeton/widgets.py +26 -23
- np_workflows/shared/__init__.py +1 -1
- np_workflows/shared/base_experiments.py +430 -308
- np_workflows/shared/npxc.py +85 -53
- np_workflows/shared/widgets.py +374 -224
- {np_workflows-1.6.89.dist-info → np_workflows-1.6.90.dist-info}/METADATA +6 -15
- np_workflows-1.6.90.dist-info/RECORD +48 -0
- {np_workflows-1.6.89.dist-info → np_workflows-1.6.90.dist-info}/WHEEL +2 -1
- np_workflows-1.6.90.dist-info/entry_points.txt +2 -0
- np_workflows-1.6.90.dist-info/top_level.txt +1 -0
- np_workflows/assets/images/logo_np_hab.png +0 -0
- np_workflows/assets/images/logo_np_vis.png +0 -0
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_00.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_01.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_02.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_03.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_04.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_05.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_06.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_07.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_08.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_09.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_10.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_11.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_12.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_13.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_14.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_15.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_16.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_17.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_18.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/flash_250ms.stim +0 -20
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/gabor_20_deg_250ms.stim +0 -30
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/old_stim.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/shuffle_reversed.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/shuffle_reversed_1st.stim +0 -5
- np_workflows/experiments/task_trained_network/camstim_scripts/stims/shuffle_reversed_2nd.stim +0 -5
- np_workflows/shared/camstim_scripts/flash_250ms.stim +0 -20
- np_workflows/shared/camstim_scripts/gabor_20_deg_250ms.stim +0 -30
- np_workflows-1.6.89.dist-info/RECORD +0 -76
- np_workflows-1.6.89.dist-info/entry_points.txt +0 -4
np_workflows/__init__.py
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
32
|
-
|
|
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 (
|
|
26
|
+
if any(tag in workflow.name for tag in ("EPHYS", "PRETEST")):
|
|
54
27
|
experiment = Ephys(mouse, user)
|
|
55
|
-
elif
|
|
28
|
+
elif "HAB" in workflow.name:
|
|
56
29
|
experiment = Hab(mouse, user)
|
|
57
|
-
elif
|
|
30
|
+
elif "OPTO" in workflow.name:
|
|
58
31
|
experiment = Opto(mouse, user)
|
|
59
|
-
elif
|
|
32
|
+
elif "TRAINING" in workflow.name:
|
|
60
33
|
experiment = Training(mouse, user)
|
|
61
34
|
else:
|
|
62
|
-
raise ValueError(
|
|
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__(
|
|
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[
|
|
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(
|
|
59
|
-
|
|
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__(
|
|
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
|
-
|
|
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(
|
|
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
|
+
)
|
|
@@ -1,17 +1,6 @@
|
|
|
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
5
|
from np_workflows.experiments.openscope_P3.main_P3_pilot import P3Session
|
|
17
6
|
|
|
@@ -20,6 +9,7 @@ global_state = {}
|
|
|
20
9
|
|
|
21
10
|
# for widget, before creating a experiment --------------------------------------------- #
|
|
22
11
|
|
|
12
|
+
|
|
23
13
|
class SelectedSession:
|
|
24
14
|
def __init__(self, session: str | P3Session, mouse: str | int | np_session.Mouse):
|
|
25
15
|
if isinstance(session, str):
|
|
@@ -48,17 +38,19 @@ def P3_workflow_widget(
|
|
|
48
38
|
options=tuple(_.value for _ in P3Session),
|
|
49
39
|
description="Session",
|
|
50
40
|
)
|
|
51
|
-
|
|
41
|
+
|
|
52
42
|
def update_selection():
|
|
53
43
|
selection.__init__(str(session_dropdown.value), str(mouse))
|
|
54
|
-
|
|
55
|
-
if
|
|
44
|
+
|
|
45
|
+
if previously_selected_value := global_state.get("selected_session"):
|
|
56
46
|
session_dropdown.value = previously_selected_value
|
|
57
47
|
update_selection()
|
|
58
|
-
|
|
48
|
+
|
|
59
49
|
console = ipw.Output()
|
|
60
50
|
with console:
|
|
61
|
-
if last_session := np_session.Mouse(selection.mouse).state.get(
|
|
51
|
+
if last_session := np_session.Mouse(selection.mouse).state.get(
|
|
52
|
+
"last_P3_session"
|
|
53
|
+
):
|
|
62
54
|
print(f"{mouse} last session: {last_session}")
|
|
63
55
|
print(f"Selected: {selection.session}")
|
|
64
56
|
|
|
@@ -74,9 +66,9 @@ def P3_workflow_widget(
|
|
|
74
66
|
update_selection()
|
|
75
67
|
with console:
|
|
76
68
|
print(f"Selected: {selection.session}")
|
|
77
|
-
global_state[
|
|
78
|
-
|
|
79
|
-
session_dropdown.observe(update, names=
|
|
69
|
+
global_state["selected_session"] = selection.session.value
|
|
70
|
+
|
|
71
|
+
session_dropdown.observe(update, names="value")
|
|
80
72
|
|
|
81
73
|
IPython.display.display(ipw.VBox([session_dropdown, console]))
|
|
82
74
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
from .main_P3_pilot import
|
|
1
|
+
from .main_P3_pilot import Ephys, Hab, new_experiment, validate_selected_workflow
|
|
2
2
|
from .P3_workflow_widget import P3_workflow_widget
|
|
@@ -1,41 +1,22 @@
|
|
|
1
|
-
import configparser
|
|
2
1
|
import contextlib
|
|
3
|
-
import copy
|
|
4
|
-
import dataclasses
|
|
5
|
-
import datetime
|
|
6
2
|
import enum
|
|
7
|
-
import functools
|
|
8
|
-
import pathlib
|
|
9
|
-
import platform
|
|
10
|
-
import shutil
|
|
11
|
-
import threading
|
|
12
3
|
import time
|
|
13
|
-
import zlib
|
|
14
|
-
from typing import ClassVar, Literal, NamedTuple, NoReturn, Optional, TypedDict
|
|
15
4
|
|
|
16
|
-
import IPython
|
|
17
|
-
import IPython.display
|
|
18
|
-
import ipywidgets as ipw
|
|
19
|
-
import np_config
|
|
20
5
|
import np_logging
|
|
21
|
-
import np_services
|
|
22
6
|
import np_session
|
|
23
|
-
import np_workflows
|
|
24
|
-
import PIL.Image
|
|
25
|
-
import pydantic
|
|
26
|
-
from pyparsing import Any
|
|
27
7
|
from np_services import (
|
|
28
|
-
Service,
|
|
29
8
|
Finalizable,
|
|
30
|
-
|
|
31
|
-
|
|
9
|
+
MouseDirector,
|
|
10
|
+
NewScaleCoordinateRecorder,
|
|
32
11
|
OpenEphys,
|
|
12
|
+
Service,
|
|
13
|
+
SessionCamstim,
|
|
33
14
|
Sync,
|
|
34
15
|
VideoMVR,
|
|
35
|
-
NewScaleCoordinateRecorder,
|
|
36
|
-
MouseDirector,
|
|
37
16
|
)
|
|
38
17
|
|
|
18
|
+
import np_workflows
|
|
19
|
+
|
|
39
20
|
logger = np_logging.getLogger(__name__)
|
|
40
21
|
|
|
41
22
|
|
|
@@ -49,16 +30,16 @@ class P3Session(enum.Enum):
|
|
|
49
30
|
|
|
50
31
|
class P3Mixin:
|
|
51
32
|
"""Provides project-specific methods and attributes, mainly related to camstim scripts."""
|
|
52
|
-
|
|
33
|
+
|
|
53
34
|
workflow: P3Session
|
|
54
35
|
"""Enum for particular workflow/session, e.g. PRETEST, HAB_60, HAB_90,
|
|
55
36
|
EPHYS."""
|
|
56
|
-
|
|
37
|
+
|
|
57
38
|
session: np_session.PipelineSession
|
|
58
39
|
mouse: np_session.Mouse
|
|
59
40
|
user: np_session.User
|
|
60
41
|
platform_json: np_session.PlatformJson
|
|
61
|
-
|
|
42
|
+
|
|
62
43
|
@property
|
|
63
44
|
def recorders(self) -> tuple[Service, ...]:
|
|
64
45
|
"""Services to be started before stimuli run, and stopped after. Session-dependent."""
|
|
@@ -70,11 +51,11 @@ class P3Mixin:
|
|
|
70
51
|
|
|
71
52
|
@property
|
|
72
53
|
def stims(self) -> tuple[Service, ...]:
|
|
73
|
-
return (SessionCamstim,
|
|
74
|
-
|
|
54
|
+
return (SessionCamstim,)
|
|
55
|
+
|
|
75
56
|
def initialize_and_test_services(self) -> None:
|
|
76
57
|
"""Configure, initialize (ie. reset), then test all services."""
|
|
77
|
-
|
|
58
|
+
|
|
78
59
|
MouseDirector.user = self.user.id
|
|
79
60
|
MouseDirector.mouse = self.mouse.id
|
|
80
61
|
|
|
@@ -92,79 +73,95 @@ class P3Mixin:
|
|
|
92
73
|
|
|
93
74
|
def update_state(self) -> None:
|
|
94
75
|
"Store useful but non-essential info."
|
|
95
|
-
self.mouse.state[
|
|
96
|
-
self.mouse.state[
|
|
76
|
+
self.mouse.state["last_session"] = self.session.id
|
|
77
|
+
self.mouse.state["last_P3_session"] = str(self.workflow)
|
|
97
78
|
if self.mouse == 366122:
|
|
98
79
|
return
|
|
99
80
|
match self.workflow:
|
|
100
81
|
case P3Session.PRETEST:
|
|
101
82
|
return
|
|
102
83
|
case P3Session.HAB:
|
|
103
|
-
self.session.project.state[
|
|
84
|
+
self.session.project.state["latest_hab"] = self.session.id
|
|
104
85
|
case P3Session.EPHYS:
|
|
105
|
-
self.session.project.state[
|
|
106
|
-
self.session.project.state[
|
|
107
|
-
|
|
86
|
+
self.session.project.state["latest_ephys"] = self.session.id
|
|
87
|
+
self.session.project.state["sessions"] = self.session.project.state.get(
|
|
88
|
+
"sessions", []
|
|
89
|
+
) + [self.session.id]
|
|
90
|
+
|
|
108
91
|
def run_stim(self) -> None:
|
|
109
92
|
|
|
110
93
|
self.update_state()
|
|
111
|
-
|
|
94
|
+
|
|
112
95
|
if not SessionCamstim.is_ready_to_start():
|
|
113
96
|
raise RuntimeError("SessionCamstim is not ready to start.")
|
|
114
|
-
|
|
115
|
-
np_logging.web(f
|
|
97
|
+
|
|
98
|
+
np_logging.web(f"P3_{self.workflow.name.lower()}").info(
|
|
99
|
+
f"Started session {self.mouse.mtrain.stage['name']}"
|
|
100
|
+
)
|
|
116
101
|
SessionCamstim.start()
|
|
117
|
-
|
|
102
|
+
|
|
118
103
|
with contextlib.suppress(Exception):
|
|
119
104
|
while not SessionCamstim.is_ready_to_start():
|
|
120
105
|
time.sleep(2.5)
|
|
121
|
-
|
|
106
|
+
|
|
122
107
|
if isinstance(SessionCamstim, Finalizable):
|
|
123
108
|
SessionCamstim.finalize()
|
|
124
109
|
|
|
125
110
|
with contextlib.suppress(Exception):
|
|
126
|
-
np_logging.web(f
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
111
|
+
np_logging.web(f"P3_{self.workflow.name.lower()}").info(
|
|
112
|
+
f"Finished session {self.mouse.mtrain.stage['name']}"
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
def copy_data_files(self) -> None:
|
|
130
116
|
super().copy_data_files()
|
|
131
|
-
|
|
117
|
+
|
|
132
118
|
# When all processing completes, camstim Agent class passes data and uuid to
|
|
133
119
|
# /camstim/lims BehaviorSession class, and write_behavior_data() writes a
|
|
134
120
|
# final .pkl with default name YYYYMMDDSSSS_mouseID_foragingID.pkl
|
|
135
121
|
# - if we have a foraging ID, we can search for that
|
|
136
|
-
if None == (
|
|
137
|
-
|
|
122
|
+
if None == (
|
|
123
|
+
stim_pkl := next(
|
|
124
|
+
self.session.npexp_path.glob(
|
|
125
|
+
f"{self.session.date:%y%m%d}*_{self.session.mouse}_*.pkl"
|
|
126
|
+
),
|
|
127
|
+
None,
|
|
128
|
+
)
|
|
129
|
+
):
|
|
130
|
+
logger.warning(
|
|
131
|
+
"Did not find stim file on npexp matching the format `YYYYMMDDSSSS_mouseID_foragingID.pkl`"
|
|
132
|
+
)
|
|
138
133
|
return
|
|
139
134
|
assert stim_pkl
|
|
140
135
|
if not self.session.platform_json.foraging_id:
|
|
141
|
-
self.session.platform_json.foraging_id = stim_pkl.stem.split(
|
|
142
|
-
new_stem = f
|
|
143
|
-
logger.debug(f
|
|
136
|
+
self.session.platform_json.foraging_id = stim_pkl.stem.split("_")[-1]
|
|
137
|
+
new_stem = f"{self.session.folder}.stim"
|
|
138
|
+
logger.debug(f"Renaming stim file copied to npexp: {stim_pkl} -> {new_stem}")
|
|
144
139
|
stim_pkl = stim_pkl.rename(stim_pkl.with_stem(new_stem))
|
|
145
|
-
|
|
140
|
+
|
|
146
141
|
# remove other stim pkl, which is nearly identical, if it was also copied
|
|
147
|
-
for pkl in self.session.npexp_path.glob(
|
|
142
|
+
for pkl in self.session.npexp_path.glob("*.pkl"):
|
|
148
143
|
if (
|
|
149
144
|
self.session.folder not in pkl.stem
|
|
150
|
-
and
|
|
151
|
-
abs(pkl.stat().st_size - stim_pkl.stat().st_size) < 1e6
|
|
145
|
+
and abs(pkl.stat().st_size - stim_pkl.stat().st_size) < 1e6
|
|
152
146
|
):
|
|
153
|
-
logger.debug(f
|
|
147
|
+
logger.debug(f"Deleting extra stim pkl copied to npexp: {pkl.stem}")
|
|
154
148
|
pkl.unlink()
|
|
155
|
-
|
|
156
|
-
|
|
149
|
+
|
|
150
|
+
|
|
157
151
|
def validate_selected_workflow(session: P3Session, mouse: np_session.Mouse) -> None:
|
|
158
|
-
for workflow in (
|
|
152
|
+
for workflow in ("hab", "ephys"):
|
|
159
153
|
if (
|
|
160
154
|
workflow in session.value.lower()
|
|
161
|
-
and workflow not in mouse.mtrain.stage[
|
|
155
|
+
and workflow not in mouse.mtrain.stage["name"].lower()
|
|
162
156
|
) or (
|
|
163
|
-
session.value.lower() ==
|
|
157
|
+
session.value.lower() == "ephys"
|
|
158
|
+
and "hab" in mouse.mtrain.stage["name"].lower()
|
|
164
159
|
):
|
|
165
|
-
raise ValueError(
|
|
160
|
+
raise ValueError(
|
|
161
|
+
f"Workflow selected ({session.value}) does not match MTrain stage ({mouse.mtrain.stage['name']}): please check cells above."
|
|
162
|
+
)
|
|
163
|
+
|
|
166
164
|
|
|
167
|
-
|
|
168
165
|
class Hab(P3Mixin, np_workflows.PipelineHab):
|
|
169
166
|
def __init__(self, *args, **kwargs):
|
|
170
167
|
self.services = (
|
|
@@ -209,9 +206,10 @@ def new_experiment(
|
|
|
209
206
|
case _:
|
|
210
207
|
raise ValueError(f"Invalid workflow type: {workflow}")
|
|
211
208
|
experiment.workflow = workflow
|
|
212
|
-
|
|
209
|
+
|
|
213
210
|
with contextlib.suppress(Exception):
|
|
214
|
-
np_logging.web(f
|
|
215
|
-
|
|
216
|
-
|
|
211
|
+
np_logging.web(f"P3_{experiment.workflow.name.lower()}").info(
|
|
212
|
+
f"{experiment} created"
|
|
213
|
+
)
|
|
217
214
|
|
|
215
|
+
return experiment
|
|
@@ -1,17 +1,6 @@
|
|
|
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
5
|
from np_workflows.experiments.openscope_barcode.main_barcode_pilot import BarcodeSession
|
|
17
6
|
|
|
@@ -20,8 +9,11 @@ global_state = {}
|
|
|
20
9
|
|
|
21
10
|
# for widget, before creating a experiment --------------------------------------------- #
|
|
22
11
|
|
|
12
|
+
|
|
23
13
|
class SelectedSession:
|
|
24
|
-
def __init__(
|
|
14
|
+
def __init__(
|
|
15
|
+
self, session: str | BarcodeSession, mouse: str | int | np_session.Mouse
|
|
16
|
+
):
|
|
25
17
|
if isinstance(session, str):
|
|
26
18
|
session = BarcodeSession(session)
|
|
27
19
|
self.session = session
|
|
@@ -48,17 +40,19 @@ def barcode_workflow_widget(
|
|
|
48
40
|
options=tuple(_.value for _ in BarcodeSession),
|
|
49
41
|
description="Session",
|
|
50
42
|
)
|
|
51
|
-
|
|
43
|
+
|
|
52
44
|
def update_selection():
|
|
53
45
|
selection.__init__(str(session_dropdown.value), str(mouse))
|
|
54
|
-
|
|
55
|
-
if
|
|
46
|
+
|
|
47
|
+
if previously_selected_value := global_state.get("selected_session"):
|
|
56
48
|
session_dropdown.value = previously_selected_value
|
|
57
49
|
update_selection()
|
|
58
|
-
|
|
50
|
+
|
|
59
51
|
console = ipw.Output()
|
|
60
52
|
with console:
|
|
61
|
-
if last_session := np_session.Mouse(selection.mouse).state.get(
|
|
53
|
+
if last_session := np_session.Mouse(selection.mouse).state.get(
|
|
54
|
+
"last_barcode_session"
|
|
55
|
+
):
|
|
62
56
|
print(f"{mouse} last session: {last_session}")
|
|
63
57
|
print(f"Selected: {selection.session}")
|
|
64
58
|
|
|
@@ -74,9 +68,9 @@ def barcode_workflow_widget(
|
|
|
74
68
|
update_selection()
|
|
75
69
|
with console:
|
|
76
70
|
print(f"Selected: {selection.session}")
|
|
77
|
-
global_state[
|
|
78
|
-
|
|
79
|
-
session_dropdown.observe(update, names=
|
|
71
|
+
global_state["selected_session"] = selection.session.value
|
|
72
|
+
|
|
73
|
+
session_dropdown.observe(update, names="value")
|
|
80
74
|
|
|
81
75
|
IPython.display.display(ipw.VBox([session_dropdown, console]))
|
|
82
76
|
|
|
@@ -5,16 +5,8 @@ May '23 OpenScope: Barcode stimuli
|
|
|
5
5
|
import argparse
|
|
6
6
|
import json
|
|
7
7
|
import logging
|
|
8
|
-
import os
|
|
9
|
-
import time
|
|
10
|
-
|
|
11
|
-
import numpy as np
|
|
12
|
-
from psychopy import visual
|
|
13
|
-
from camstim import Foraging
|
|
14
|
-
from camstim import Stimulus_v2
|
|
15
|
-
from camstim import SweepStim_v2
|
|
16
|
-
from camstim import Warp, Window
|
|
17
8
|
|
|
9
|
+
from camstim import Foraging, Stimulus_v2, SweepStim_v2, Warp, Window
|
|
18
10
|
|
|
19
11
|
# get params ------------------------------------------------------------------
|
|
20
12
|
# stored in json file -
|
|
@@ -29,7 +21,7 @@ parser.add_argument(
|
|
|
29
21
|
)
|
|
30
22
|
args, _ = parser.parse_known_args()
|
|
31
23
|
|
|
32
|
-
with open(args.params_path
|
|
24
|
+
with open(args.params_path) as f:
|
|
33
25
|
json_params = json.load(f)
|
|
34
26
|
|
|
35
27
|
# Create display window
|
|
@@ -41,6 +33,7 @@ window = Window(
|
|
|
41
33
|
warp=Warp.Spherical,
|
|
42
34
|
)
|
|
43
35
|
|
|
36
|
+
|
|
44
37
|
# patch the Stimulus_v2 class to allow for serializing without large arrays
|
|
45
38
|
# ----------------------------------------------------------------------------
|
|
46
39
|
class Stimulus_v2_MinusFrameArrays(Stimulus_v2):
|
|
@@ -56,11 +49,12 @@ class Stimulus_v2_MinusFrameArrays(Stimulus_v2):
|
|
|
56
49
|
self.sweep_table = None
|
|
57
50
|
self.sweep_params = self.sweep_params.keys()
|
|
58
51
|
self_dict = self.__dict__
|
|
59
|
-
del self_dict[
|
|
60
|
-
del self_dict[
|
|
61
|
-
self_dict[
|
|
52
|
+
del self_dict["sweep_frames"]
|
|
53
|
+
del self_dict["sweep_order"]
|
|
54
|
+
self_dict["stim"] = str(self_dict["stim"])
|
|
62
55
|
return wecanpicklethat(self_dict)
|
|
63
|
-
|
|
56
|
+
|
|
57
|
+
|
|
64
58
|
# ----------------------------------------------------------------------------
|
|
65
59
|
# setup mapping stim
|
|
66
60
|
"""from mapping_script_v2.py"""
|