np-workflows 1.6.87__py3-none-any.whl → 1.6.91__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 +75 -0
- np_workflows/experiments/openscope_P3/__init__.py +2 -0
- np_workflows/experiments/openscope_P3/main_P3_pilot.py +215 -0
- 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 +2 -0
- np_workflows/experiments/openscope_v2/main_v2_pilot.py +215 -0
- np_workflows/experiments/openscope_v2/v2_workflow_widget.py +75 -0
- 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.87.dist-info → np_workflows-1.6.91.dist-info}/METADATA +7 -21
- np_workflows-1.6.91.dist-info/RECORD +48 -0
- {np_workflows-1.6.87.dist-info → np_workflows-1.6.91.dist-info}/WHEEL +2 -1
- np_workflows-1.6.91.dist-info/entry_points.txt +2 -0
- np_workflows-1.6.91.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.87.dist-info/RECORD +0 -70
- np_workflows-1.6.87.dist-info/entry_points.txt +0 -4
|
@@ -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 VippoSession(enum.Enum):
|
|
|
49
30
|
|
|
50
31
|
class VippoMixin:
|
|
51
32
|
"""Provides project-specific methods and attributes, mainly related to camstim scripts."""
|
|
52
|
-
|
|
33
|
+
|
|
53
34
|
workflow: VippoSession
|
|
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 VippoMixin:
|
|
|
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 VippoMixin:
|
|
|
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_vippo_session"] = str(self.workflow)
|
|
97
78
|
if self.mouse == 366122:
|
|
98
79
|
return
|
|
99
80
|
match self.workflow:
|
|
100
81
|
case VippoSession.PRETEST:
|
|
101
82
|
return
|
|
102
83
|
case VippoSession.HAB:
|
|
103
|
-
self.session.project.state[
|
|
84
|
+
self.session.project.state["latest_hab"] = self.session.id
|
|
104
85
|
case VippoSession.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"vippo_{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"vippo_{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: VippoSession, 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(VippoMixin, 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"vippo_{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_vippo.main_vippo_pilot import VippoSession
|
|
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 | VippoSession, mouse: str | int | np_session.Mouse
|
|
16
|
+
):
|
|
25
17
|
if isinstance(session, str):
|
|
26
18
|
session = VippoSession(session)
|
|
27
19
|
self.session = session
|
|
@@ -48,17 +40,19 @@ def vippo_workflow_widget(
|
|
|
48
40
|
options=tuple(_.value for _ in VippoSession),
|
|
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_vippo_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 vippo_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
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
from .main_ttn_pilot import
|
|
1
|
+
from .main_ttn_pilot import Ephys, Hab, new_experiment
|
|
2
2
|
from .ttn_session_widget import stim_session_select_widget
|
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
import pathlib
|
|
2
2
|
|
|
3
|
-
out_path = pathlib.Path(__file__).parent /
|
|
4
|
-
movie_path =
|
|
3
|
+
out_path = pathlib.Path(__file__).parent / "stims"
|
|
4
|
+
movie_path = "C:\\ProgramData\\StimulusFiles\\dev\\"
|
|
5
5
|
|
|
6
6
|
paths = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
"old_stim.stim": movie_path + "old_movie\\ds_unwarped_15_test_movie_one.npy",
|
|
8
|
+
"shuffle_reversed.stim": movie_path + "new_movies\\ds_unwarped_15_reverse.npy",
|
|
9
|
+
"shuffle_reversed_1st.stim": movie_path
|
|
10
|
+
+ "new_movies\\ds_unwarped_15_reverse_first_half.npy",
|
|
11
|
+
"shuffle_reversed_2nd.stim": movie_path
|
|
12
|
+
+ "new_movies\\ds_unwarped_15_reverse_second_half.npy",
|
|
11
13
|
}
|
|
12
|
-
paths.update(
|
|
14
|
+
paths.update(
|
|
15
|
+
{
|
|
16
|
+
"densely_annotated_%02d.stim" % i: movie_path
|
|
17
|
+
+ "tt_stim_dense\\ds_unwarped_15_clip_%02d.npy" % i
|
|
18
|
+
for i in range(19)
|
|
19
|
+
}
|
|
20
|
+
)
|
|
13
21
|
|
|
14
22
|
|
|
15
|
-
if __name__ ==
|
|
23
|
+
if __name__ == "__main__":
|
|
16
24
|
out_path.mkdir(exist_ok=True, parents=True)
|
|
17
25
|
for file, path in paths.items():
|
|
18
|
-
with open(out_path / file,
|
|
19
|
-
f.write(
|
|
20
|
-
f.write(
|
|
21
|
-
f.write(
|
|
22
|
-
f.write(
|
|
23
|
-
f.write(
|
|
26
|
+
with open(out_path / file, "w") as f:
|
|
27
|
+
f.write("import os, shutil\n")
|
|
28
|
+
f.write("import numpy as np\n")
|
|
29
|
+
f.write("from camstim.misc import ImageStimNumpyuByte, checkDirs\n")
|
|
30
|
+
f.write("moviesource = " + "r'" + path + "'" + "\n")
|
|
31
|
+
f.write(
|
|
32
|
+
"stimulus = MovieStim(movie_path=moviesource,window=window,frame_length=2.0/60.0,size=(1920, 1200),start_time=0.0,stop_time=None,flip_v=True,runs=10,)"
|
|
33
|
+
)
|
|
@@ -1,68 +1,81 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Oct'22 task-trained ephys stimuli
|
|
3
3
|
"""
|
|
4
|
-
|
|
5
|
-
from
|
|
6
|
-
from camstim import Foraging
|
|
7
|
-
from camstim import Window, Warp
|
|
8
|
-
import numpy as np
|
|
4
|
+
|
|
5
|
+
# from psychopy import visual
|
|
6
|
+
from camstim import Foraging, Stimulus, SweepStim, Warp, Window
|
|
9
7
|
|
|
10
8
|
# Create display window
|
|
11
|
-
window = Window(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
warp=Warp.Disabled
|
|
15
|
-
)
|
|
9
|
+
window = Window(
|
|
10
|
+
fullscr=True, monitor="GammaCorrect30", screen=0, warp=Warp.Disabled # MUST CONFIRM
|
|
11
|
+
)
|
|
16
12
|
|
|
17
|
-
movie_path =
|
|
13
|
+
movie_path = "C:\\Users\\svc_flex4\\tt_testing\\"
|
|
18
14
|
|
|
19
15
|
session = 1
|
|
20
16
|
segment_secs = (
|
|
21
|
-
[(
|
|
22
|
-
[
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
[("old_stim.stim", 40)] * 25
|
|
18
|
+
+ [
|
|
19
|
+
("shuffle_reversed.stim", 40),
|
|
20
|
+
("shuffle_reversed_1st.stim", 40),
|
|
21
|
+
("shuffle_reversed_2nd.stim", 40),
|
|
22
|
+
]
|
|
23
|
+
* 8
|
|
24
|
+
+ [("densely_annotated_%02d.stim" % i, 60) for i in range(19)] * 2
|
|
25
|
+
+ [("old_stim.stim", 40)] * 25
|
|
26
|
+
+ [
|
|
27
|
+
("shuffle_reversed.stim", 40),
|
|
28
|
+
("shuffle_reversed_1st.stim", 40),
|
|
29
|
+
("shuffle_reversed_2nd.stim", 40),
|
|
30
|
+
]
|
|
31
|
+
* 8
|
|
26
32
|
) # 6200 seconds = 103 minutes, 20 secs
|
|
27
|
-
|
|
33
|
+
|
|
28
34
|
num_segments = len(segment_secs)
|
|
29
35
|
|
|
30
|
-
#build the stimulus array
|
|
36
|
+
# build the stimulus array
|
|
31
37
|
frames_per_sec = 30.0
|
|
32
38
|
stim = []
|
|
33
39
|
total_movie_sec = 0
|
|
34
40
|
|
|
35
41
|
for file, length in segment_secs:
|
|
36
|
-
segment = Stimulus.from_file(movie_path+file, window)
|
|
37
|
-
segment_ds = [(total_movie_sec,total_movie_sec+length)]
|
|
42
|
+
segment = Stimulus.from_file(movie_path + file, window)
|
|
43
|
+
segment_ds = [(total_movie_sec, total_movie_sec + length)]
|
|
38
44
|
segment.set_display_sequence(segment_ds)
|
|
39
|
-
|
|
45
|
+
|
|
40
46
|
total_movie_sec += length
|
|
41
|
-
|
|
47
|
+
|
|
42
48
|
stim.append(segment)
|
|
43
|
-
|
|
44
|
-
params = {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
|
|
50
|
+
params = {
|
|
51
|
+
"syncsqr": True,
|
|
52
|
+
"syncsqrloc": (875, 550),
|
|
53
|
+
"syncsqrsize": (150, 150),
|
|
54
|
+
"syncpulse": True,
|
|
55
|
+
"syncpulseport": 1,
|
|
56
|
+
"syncpulselines": [5, 6], # frame, start/stop
|
|
57
|
+
"trigger_delay_sec": 5.0,
|
|
58
|
+
}
|
|
51
59
|
|
|
52
60
|
# create SweepStim instance
|
|
53
|
-
ss = SweepStim(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
61
|
+
ss = SweepStim(
|
|
62
|
+
window,
|
|
63
|
+
stimuli=stim,
|
|
64
|
+
pre_blank_sec=2,
|
|
65
|
+
post_blank_sec=2,
|
|
66
|
+
params=params,
|
|
67
|
+
)
|
|
59
68
|
|
|
60
69
|
# add in foraging so we can track wheel, potentially give rewards, etc
|
|
61
|
-
f = Foraging(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
f = Foraging(
|
|
71
|
+
window=window,
|
|
72
|
+
auto_update=False,
|
|
73
|
+
params=params,
|
|
74
|
+
nidaq_tasks={
|
|
75
|
+
"digital_input": ss.di,
|
|
76
|
+
"digital_output": ss.do,
|
|
77
|
+
},
|
|
78
|
+
) # share di and do with SS
|
|
66
79
|
ss.add_item(f, "foraging")
|
|
67
80
|
|
|
68
81
|
# run it
|
|
@@ -4,18 +4,9 @@ Oct'22 task-trained ephys stimuli
|
|
|
4
4
|
|
|
5
5
|
import argparse
|
|
6
6
|
import json
|
|
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, MovieStim
|
|
16
|
-
from camstim import Warp, Window
|
|
17
|
-
from camstim.misc import wecanpicklethat
|
|
18
7
|
|
|
8
|
+
from camstim import Foraging, MovieStim, Stimulus_v2, SweepStim_v2, Warp, Window
|
|
9
|
+
from camstim.misc import wecanpicklethat
|
|
19
10
|
|
|
20
11
|
# get params ------------------------------------------------------------------
|
|
21
12
|
# stored in json file -
|
|
@@ -30,7 +21,7 @@ parser.add_argument(
|
|
|
30
21
|
)
|
|
31
22
|
args, _ = parser.parse_known_args()
|
|
32
23
|
|
|
33
|
-
with open(args.params_path
|
|
24
|
+
with open(args.params_path) as f:
|
|
34
25
|
json_params = json.load(f)
|
|
35
26
|
|
|
36
27
|
# Create display window
|
|
@@ -45,6 +36,7 @@ window = Window(
|
|
|
45
36
|
# monkey-patch MovieStim to serialize without large redundant arrays
|
|
46
37
|
# ----------------------------------------------------------------------------
|
|
47
38
|
|
|
39
|
+
|
|
48
40
|
def package(self):
|
|
49
41
|
"""
|
|
50
42
|
Package for serializing - minus large arrays of frame timing/order.
|
|
@@ -53,12 +45,13 @@ def package(self):
|
|
|
53
45
|
self.sweep_table = None
|
|
54
46
|
self.sweep_params = self.sweep_params.keys()
|
|
55
47
|
self_dict = self.__dict__
|
|
56
|
-
del self_dict[
|
|
57
|
-
del self_dict[
|
|
58
|
-
del self_dict[
|
|
59
|
-
self_dict[
|
|
48
|
+
del self_dict["sweep_frames"]
|
|
49
|
+
del self_dict["sweep_order"]
|
|
50
|
+
del self_dict["frame_list"]
|
|
51
|
+
self_dict["stim"] = str(self_dict["stim"])
|
|
60
52
|
return wecanpicklethat(self_dict)
|
|
61
53
|
|
|
54
|
+
|
|
62
55
|
MovieStim.package = package
|
|
63
56
|
|
|
64
57
|
# setup main stim
|
|
@@ -80,7 +73,8 @@ segment_stim_secs = (
|
|
|
80
73
|
("shuffle_reversed.stim", reversed_sec),
|
|
81
74
|
("shuffle_reversed_1st.stim", reversed_sec),
|
|
82
75
|
("shuffle_reversed_2nd.stim", reversed_sec),
|
|
83
|
-
]
|
|
76
|
+
]
|
|
77
|
+
* reversed_repeats
|
|
84
78
|
+ [("densely_annotated_%02d.stim" % i, annotated_sec) for i in range(19)]
|
|
85
79
|
* annotated_repeats
|
|
86
80
|
+ [("old_stim.stim", old_sec)] * old_repeats
|
|
@@ -88,15 +82,18 @@ segment_stim_secs = (
|
|
|
88
82
|
("shuffle_reversed.stim", reversed_sec),
|
|
89
83
|
("shuffle_reversed_1st.stim", reversed_sec),
|
|
90
84
|
("shuffle_reversed_2nd.stim", reversed_sec),
|
|
91
|
-
]
|
|
85
|
+
]
|
|
86
|
+
* reversed_repeats
|
|
92
87
|
)
|
|
93
88
|
|
|
94
89
|
# setup stim list and timing
|
|
95
|
-
cumulative_duration_sec = (
|
|
96
|
-
|
|
97
|
-
)
|
|
90
|
+
cumulative_duration_sec = main_sequence_start_sec = (
|
|
91
|
+
0 # if stims are daisy-chained within one script, this should be the end of the prev stim
|
|
92
|
+
)
|
|
98
93
|
for stim_file, duration_sec in segment_stim_secs:
|
|
99
|
-
segment = Stimulus_v2.from_file(
|
|
94
|
+
segment = Stimulus_v2.from_file(
|
|
95
|
+
stim_file, window
|
|
96
|
+
) # stim file actually instantiates MovieStim
|
|
100
97
|
segment_ds = [(cumulative_duration_sec, cumulative_duration_sec + duration_sec)]
|
|
101
98
|
segment.set_display_sequence(segment_ds)
|
|
102
99
|
|
|
@@ -5,16 +5,8 @@ Oct'22 task-trained ephys 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"""
|