np-workflows 1.6.89__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.
Files changed (76) hide show
  1. np_workflows/__init__.py +3 -5
  2. np_workflows/experiments/dynamic_routing/main.py +20 -41
  3. np_workflows/experiments/dynamic_routing/widgets.py +29 -24
  4. np_workflows/experiments/openscope_P3/P3_workflow_widget.py +11 -19
  5. np_workflows/experiments/openscope_P3/__init__.py +1 -1
  6. np_workflows/experiments/openscope_P3/main_P3_pilot.py +66 -68
  7. np_workflows/experiments/openscope_barcode/__init__.py +1 -1
  8. np_workflows/experiments/openscope_barcode/barcode_workflow_widget.py +14 -20
  9. np_workflows/experiments/openscope_barcode/camstim_scripts/barcode_mapping_script.py +8 -14
  10. np_workflows/experiments/openscope_barcode/camstim_scripts/barcode_opto_script.py +121 -68
  11. np_workflows/experiments/openscope_barcode/main_barcode_pilot.py +69 -69
  12. np_workflows/experiments/openscope_loop/__init__.py +1 -1
  13. np_workflows/experiments/openscope_loop/camstim_scripts/barcode_mapping_script.py +8 -14
  14. np_workflows/experiments/openscope_loop/camstim_scripts/barcode_opto_script.py +121 -68
  15. np_workflows/experiments/openscope_loop/loop_workflow_widget.py +11 -19
  16. np_workflows/experiments/openscope_loop/main_loop_pilot.py +66 -68
  17. np_workflows/experiments/openscope_psycode/__init__.py +1 -1
  18. np_workflows/experiments/openscope_psycode/main_psycode_pilot.py +69 -69
  19. np_workflows/experiments/openscope_psycode/psycode_workflow_widget.py +14 -20
  20. np_workflows/experiments/openscope_v2/__init__.py +1 -1
  21. np_workflows/experiments/openscope_v2/main_v2_pilot.py +66 -68
  22. np_workflows/experiments/openscope_v2/v2_workflow_widget.py +11 -19
  23. np_workflows/experiments/openscope_vippo/__init__.py +1 -1
  24. np_workflows/experiments/openscope_vippo/main_vippo_pilot.py +66 -68
  25. np_workflows/experiments/openscope_vippo/vippo_workflow_widget.py +14 -20
  26. np_workflows/experiments/task_trained_network/__init__.py +1 -1
  27. np_workflows/experiments/task_trained_network/camstim_scripts/make_tt_stims.py +24 -14
  28. np_workflows/experiments/task_trained_network/camstim_scripts/oct22_tt_stim_script.py +54 -41
  29. np_workflows/experiments/task_trained_network/camstim_scripts/ttn_main_script.py +19 -22
  30. np_workflows/experiments/task_trained_network/camstim_scripts/ttn_mapping_script.py +8 -14
  31. np_workflows/experiments/task_trained_network/camstim_scripts/ttn_opto_script.py +121 -68
  32. np_workflows/experiments/task_trained_network/main_ttn_pilot.py +73 -68
  33. np_workflows/experiments/task_trained_network/ttn_session_widget.py +11 -19
  34. np_workflows/experiments/task_trained_network/ttn_stim_config.py +23 -19
  35. np_workflows/experiments/templeton/main.py +18 -41
  36. np_workflows/experiments/templeton/widgets.py +26 -23
  37. np_workflows/shared/__init__.py +1 -1
  38. np_workflows/shared/base_experiments.py +430 -308
  39. np_workflows/shared/npxc.py +85 -53
  40. np_workflows/shared/widgets.py +374 -224
  41. {np_workflows-1.6.89.dist-info → np_workflows-1.6.91.dist-info}/METADATA +7 -21
  42. np_workflows-1.6.91.dist-info/RECORD +48 -0
  43. {np_workflows-1.6.89.dist-info → np_workflows-1.6.91.dist-info}/WHEEL +2 -1
  44. np_workflows-1.6.91.dist-info/entry_points.txt +2 -0
  45. np_workflows-1.6.91.dist-info/top_level.txt +1 -0
  46. np_workflows/assets/images/logo_np_hab.png +0 -0
  47. np_workflows/assets/images/logo_np_vis.png +0 -0
  48. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_00.stim +0 -5
  49. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_01.stim +0 -5
  50. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_02.stim +0 -5
  51. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_03.stim +0 -5
  52. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_04.stim +0 -5
  53. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_05.stim +0 -5
  54. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_06.stim +0 -5
  55. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_07.stim +0 -5
  56. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_08.stim +0 -5
  57. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_09.stim +0 -5
  58. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_10.stim +0 -5
  59. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_11.stim +0 -5
  60. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_12.stim +0 -5
  61. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_13.stim +0 -5
  62. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_14.stim +0 -5
  63. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_15.stim +0 -5
  64. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_16.stim +0 -5
  65. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_17.stim +0 -5
  66. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_18.stim +0 -5
  67. np_workflows/experiments/task_trained_network/camstim_scripts/stims/flash_250ms.stim +0 -20
  68. np_workflows/experiments/task_trained_network/camstim_scripts/stims/gabor_20_deg_250ms.stim +0 -30
  69. np_workflows/experiments/task_trained_network/camstim_scripts/stims/old_stim.stim +0 -5
  70. np_workflows/experiments/task_trained_network/camstim_scripts/stims/shuffle_reversed.stim +0 -5
  71. np_workflows/experiments/task_trained_network/camstim_scripts/stims/shuffle_reversed_1st.stim +0 -5
  72. np_workflows/experiments/task_trained_network/camstim_scripts/stims/shuffle_reversed_2nd.stim +0 -5
  73. np_workflows/shared/camstim_scripts/flash_250ms.stim +0 -20
  74. np_workflows/shared/camstim_scripts/gabor_20_deg_250ms.stim +0 -30
  75. np_workflows-1.6.89.dist-info/RECORD +0 -76
  76. np_workflows-1.6.89.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
- ScriptCamstim, SessionCamstim,
31
- SessionCamstim,
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 PsyCodeSession(enum.Enum):
49
30
 
50
31
  class PsyCodeMixin:
51
32
  """Provides project-specific methods and attributes, mainly related to camstim scripts."""
52
-
33
+
53
34
  workflow: PsyCodeSession
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 PsyCodeMixin:
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,97 @@ class PsyCodeMixin:
92
73
 
93
74
  def update_state(self) -> None:
94
75
  "Store useful but non-essential info."
95
- self.mouse.state['last_session'] = self.session.id
96
- self.mouse.state['last_PsyCode_session'] = str(self.workflow)
76
+ self.mouse.state["last_session"] = self.session.id
77
+ self.mouse.state["last_PsyCode_session"] = str(self.workflow)
97
78
  if self.mouse == 366122:
98
79
  return
99
80
  match self.workflow:
100
81
  case PsyCodeSession.PRETEST:
101
82
  return
102
83
  case PsyCodeSession.HAB:
103
- self.session.project.state['latest_hab'] = self.session.id
84
+ self.session.project.state["latest_hab"] = self.session.id
104
85
  case PsyCodeSession.EPHYS:
105
- self.session.project.state['latest_ephys'] = self.session.id
106
- self.session.project.state['sessions'] = self.session.project.state.get('sessions', []) + [self.session.id]
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'PsyCode_{self.workflow.name.lower()}').info(f"Started session {self.mouse.mtrain.stage['name']}")
97
+
98
+ np_logging.web(f"PsyCode_{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'PsyCode_{self.workflow.name.lower()}').info(f"Finished session {self.mouse.mtrain.stage['name']}")
127
-
128
-
129
- def copy_data_files(self) -> None:
111
+ np_logging.web(f"PsyCode_{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 == (stim_pkl := next(self.session.npexp_path.glob(f'{self.session.date:%y%m%d}*_{self.session.mouse}_*.pkl'), None)):
137
- logger.warning('Did not find stim file on npexp matching the format `YYYYMMDDSSSS_mouseID_foragingID.pkl`')
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('_')[-1]
142
- new_stem = f'{self.session.folder}.stim'
143
- logger.debug(f'Renaming stim file copied to npexp: {stim_pkl} -> {new_stem}')
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('*.pkl'):
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'Deleting extra stim pkl copied to npexp: {pkl.stem}')
147
+ logger.debug(f"Deleting extra stim pkl copied to npexp: {pkl.stem}")
154
148
  pkl.unlink()
155
-
156
-
157
- def validate_selected_workflow(session: PsyCodeSession, mouse: np_session.Mouse) -> None:
158
- for workflow in ('hab', 'ephys'):
149
+
150
+
151
+ def validate_selected_workflow(
152
+ session: PsyCodeSession, mouse: np_session.Mouse
153
+ ) -> None:
154
+ for workflow in ("hab", "ephys"):
159
155
  if (
160
156
  workflow in session.value.lower()
161
- and workflow not in mouse.mtrain.stage['name'].lower()
157
+ and workflow not in mouse.mtrain.stage["name"].lower()
162
158
  ) or (
163
- session.value.lower() == 'ephys' and 'hab' in mouse.mtrain.stage['name'].lower()
159
+ session.value.lower() == "ephys"
160
+ and "hab" in mouse.mtrain.stage["name"].lower()
164
161
  ):
165
- raise ValueError(f"Workflow selected ({session.value}) does not match MTrain stage ({mouse.mtrain.stage['name']}): please check cells above.")
162
+ raise ValueError(
163
+ f"Workflow selected ({session.value}) does not match MTrain stage ({mouse.mtrain.stage['name']}): please check cells above."
164
+ )
165
+
166
166
 
167
-
168
167
  class Hab(PsyCodeMixin, np_workflows.PipelineHab):
169
168
  def __init__(self, *args, **kwargs):
170
169
  self.services = (
@@ -209,9 +208,10 @@ def new_experiment(
209
208
  case _:
210
209
  raise ValueError(f"Invalid workflow type: {workflow}")
211
210
  experiment.workflow = workflow
212
-
211
+
213
212
  with contextlib.suppress(Exception):
214
- np_logging.web(f'PsyCode_{experiment.workflow.name.lower()}').info(f"{experiment} created")
215
-
216
- return experiment
213
+ np_logging.web(f"PsyCode_{experiment.workflow.name.lower()}").info(
214
+ f"{experiment} created"
215
+ )
217
216
 
217
+ 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_psycode.main_psycode_pilot import PsyCodeSession
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__(self, session: str | PsyCodeSession, mouse: str | int | np_session.Mouse):
14
+ def __init__(
15
+ self, session: str | PsyCodeSession, mouse: str | int | np_session.Mouse
16
+ ):
25
17
  if isinstance(session, str):
26
18
  session = PsyCodeSession(session)
27
19
  self.session = session
@@ -48,17 +40,19 @@ def PsyCode_workflow_widget(
48
40
  options=tuple(_.value for _ in PsyCodeSession),
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 (previously_selected_value := global_state.get('selected_session')):
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('last_PsyCode_session'):
53
+ if last_session := np_session.Mouse(selection.mouse).state.get(
54
+ "last_PsyCode_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 PsyCode_workflow_widget(
74
68
  update_selection()
75
69
  with console:
76
70
  print(f"Selected: {selection.session}")
77
- global_state['selected_session'] = selection.session.value
78
-
79
- session_dropdown.observe(update, names='value')
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_V2_pilot import new_experiment, Hab, Ephys, validate_selected_workflow
1
+ from .main_V2_pilot import Ephys, Hab, new_experiment, validate_selected_workflow
2
2
  from .V2_workflow_widget import V2_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
- ScriptCamstim, SessionCamstim,
31
- SessionCamstim,
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 V2Session(enum.Enum):
49
30
 
50
31
  class V2Mixin:
51
32
  """Provides project-specific methods and attributes, mainly related to camstim scripts."""
52
-
33
+
53
34
  workflow: V2Session
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 V2Mixin:
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 V2Mixin:
92
73
 
93
74
  def update_state(self) -> None:
94
75
  "Store useful but non-essential info."
95
- self.mouse.state['last_session'] = self.session.id
96
- self.mouse.state['last_V2_session'] = str(self.workflow)
76
+ self.mouse.state["last_session"] = self.session.id
77
+ self.mouse.state["last_V2_session"] = str(self.workflow)
97
78
  if self.mouse == 366122:
98
79
  return
99
80
  match self.workflow:
100
81
  case V2Session.PRETEST:
101
82
  return
102
83
  case V2Session.HAB:
103
- self.session.project.state['latest_hab'] = self.session.id
84
+ self.session.project.state["latest_hab"] = self.session.id
104
85
  case V2Session.EPHYS:
105
- self.session.project.state['latest_ephys'] = self.session.id
106
- self.session.project.state['sessions'] = self.session.project.state.get('sessions', []) + [self.session.id]
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'V2_{self.workflow.name.lower()}').info(f"Started session {self.mouse.mtrain.stage['name']}")
97
+
98
+ np_logging.web(f"V2_{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'V2_{self.workflow.name.lower()}').info(f"Finished session {self.mouse.mtrain.stage['name']}")
127
-
128
-
129
- def copy_data_files(self) -> None:
111
+ np_logging.web(f"V2_{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 == (stim_pkl := next(self.session.npexp_path.glob(f'{self.session.date:%y%m%d}*_{self.session.mouse}_*.pkl'), None)):
137
- logger.warning('Did not find stim file on npexp matching the format `YYYYMMDDSSSS_mouseID_foragingID.pkl`')
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('_')[-1]
142
- new_stem = f'{self.session.folder}.stim'
143
- logger.debug(f'Renaming stim file copied to npexp: {stim_pkl} -> {new_stem}')
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('*.pkl'):
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'Deleting extra stim pkl copied to npexp: {pkl.stem}')
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: V2Session, mouse: np_session.Mouse) -> None:
158
- for workflow in ('hab', 'ephys'):
152
+ for workflow in ("hab", "ephys"):
159
153
  if (
160
154
  workflow in session.value.lower()
161
- and workflow not in mouse.mtrain.stage['name'].lower()
155
+ and workflow not in mouse.mtrain.stage["name"].lower()
162
156
  ) or (
163
- session.value.lower() == 'ephys' and 'hab' in mouse.mtrain.stage['name'].lower()
157
+ session.value.lower() == "ephys"
158
+ and "hab" in mouse.mtrain.stage["name"].lower()
164
159
  ):
165
- raise ValueError(f"Workflow selected ({session.value}) does not match MTrain stage ({mouse.mtrain.stage['name']}): please check cells above.")
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(V2Mixin, 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'V2_{experiment.workflow.name.lower()}').info(f"{experiment} created")
215
-
216
- return experiment
211
+ np_logging.web(f"V2_{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_V2.main_V2_pilot import V2Session
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 | V2Session, mouse: str | int | np_session.Mouse):
25
15
  if isinstance(session, str):
@@ -48,17 +38,19 @@ def V2_workflow_widget(
48
38
  options=tuple(_.value for _ in V2Session),
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 (previously_selected_value := global_state.get('selected_session')):
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('last_V2_session'):
51
+ if last_session := np_session.Mouse(selection.mouse).state.get(
52
+ "last_V2_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 V2_workflow_widget(
74
66
  update_selection()
75
67
  with console:
76
68
  print(f"Selected: {selection.session}")
77
- global_state['selected_session'] = selection.session.value
78
-
79
- session_dropdown.observe(update, names='value')
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_vippo_pilot import new_experiment, Hab, Ephys, validate_selected_workflow
1
+ from .main_vippo_pilot import Ephys, Hab, new_experiment, validate_selected_workflow
2
2
  from .vippo_workflow_widget import vippo_workflow_widget