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.
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 +75 -0
  5. np_workflows/experiments/openscope_P3/__init__.py +2 -0
  6. np_workflows/experiments/openscope_P3/main_P3_pilot.py +215 -0
  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 +2 -0
  21. np_workflows/experiments/openscope_v2/main_v2_pilot.py +215 -0
  22. np_workflows/experiments/openscope_v2/v2_workflow_widget.py +75 -0
  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.87.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.87.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.87.dist-info/RECORD +0 -70
  76. np_workflows-1.6.87.dist-info/entry_points.txt +0 -4
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  """
3
2
  optotagging.py
4
3
 
@@ -9,37 +8,30 @@ by joshs@alleninstitute.org
9
8
  (c) 2018 Allen Institute for Brain Science
10
9
 
11
10
  """
12
- import camstim # ensures "magic" gets setup properly by importing first
13
- import logging # must occur after camstim import for "magic"
14
- from camstim.zro import agent
15
-
16
- import numpy as np
17
- from toolbox.IO.nidaq import AnalogOutput
18
- from toolbox.IO.nidaq import DigitalOutput
19
11
 
20
12
  import datetime
21
- import numpy as np
22
- import time
13
+ import logging # must occur after camstim import for "magic"
23
14
  import pickle as pkl
15
+ import time
24
16
 
17
+ import numpy as np
18
+ from camstim.zro import agent
19
+ from toolbox.IO.nidaq import AnalogOutput, DigitalOutput
25
20
 
26
21
  # %%
27
22
 
28
23
 
29
- def run_optotagging(levels, conditions, waveforms, isis, sampleRate=10000.):
30
-
31
- from toolbox.IO.nidaq import AnalogOutput
32
- from toolbox.IO.nidaq import DigitalOutput
24
+ def run_optotagging(levels, conditions, waveforms, isis, sampleRate=10000.0):
33
25
 
34
26
  sweep_on = np.array([0, 0, 1, 0, 0, 0, 0, 0], dtype=np.uint8)
35
27
  stim_on = np.array([0, 0, 1, 1, 0, 0, 0, 0], dtype=np.uint8)
36
28
  stim_off = np.array([0, 0, 1, 0, 0, 0, 0, 0], dtype=np.uint8)
37
29
  sweep_off = np.array([0, 0, 0, 0, 0, 0, 0, 0], dtype=np.uint8)
38
30
 
39
- ao = AnalogOutput('Dev1', channels=[1])
31
+ ao = AnalogOutput("Dev1", channels=[1])
40
32
  ao.cfg_sample_clock(sampleRate)
41
33
 
42
- do = DigitalOutput('Dev1', 2)
34
+ do = DigitalOutput("Dev1", 2)
43
35
 
44
36
  do.start()
45
37
  ao.start()
@@ -62,71 +54,123 @@ def run_optotagging(levels, conditions, waveforms, isis, sampleRate=10000.):
62
54
  do.clear()
63
55
  ao.clear()
64
56
 
57
+
65
58
  # %%
66
59
 
67
60
 
68
- def generatePulseTrain(pulseWidth, pulseInterval, numRepeats, riseTime, sampleRate=10000.):
61
+ def generatePulseTrain(
62
+ pulseWidth, pulseInterval, numRepeats, riseTime, sampleRate=10000.0
63
+ ):
69
64
 
70
65
  data = np.zeros((int(sampleRate),), dtype=np.float64)
71
- # rise_samples =
66
+ # rise_samples =
72
67
 
73
68
  rise_and_fall = (
74
- ((1 - np.cos(np.arange(sampleRate*riseTime/1000., dtype=np.float64)*2*np.pi/10))+1)-1)/2
69
+ (
70
+ (
71
+ 1
72
+ - np.cos(
73
+ np.arange(sampleRate * riseTime / 1000.0, dtype=np.float64)
74
+ * 2
75
+ * np.pi
76
+ / 10
77
+ )
78
+ )
79
+ + 1
80
+ )
81
+ - 1
82
+ ) / 2
75
83
  half_length = rise_and_fall.size / 2
76
84
  rise = rise_and_fall[:half_length]
77
85
  fall = rise_and_fall[half_length:]
78
86
 
79
- peak_samples = int(sampleRate*(pulseWidth-riseTime*2)/1000)
87
+ peak_samples = int(sampleRate * (pulseWidth - riseTime * 2) / 1000)
80
88
  peak = np.ones((peak_samples,))
81
89
 
82
- pulse = np.concatenate((rise,
83
- peak,
84
- fall))
90
+ pulse = np.concatenate((rise, peak, fall))
85
91
 
86
- interval = int(pulseInterval*sampleRate/1000.)
92
+ interval = int(pulseInterval * sampleRate / 1000.0)
87
93
 
88
94
  for i in range(0, numRepeats):
89
- data[i*interval:i*interval+pulse.size] = pulse
95
+ data[i * interval : i * interval + pulse.size] = pulse
90
96
 
91
97
  return data
92
98
 
93
99
 
94
100
  # %% create waveforms
95
101
 
96
- def optotagging(mouseID, operation_mode='experiment', level_list=[1.15, 1.28, 1.345], genotype=None):
102
+
103
+ def optotagging(
104
+ mouseID, operation_mode="experiment", level_list=[1.15, 1.28, 1.345], genotype=None
105
+ ):
97
106
 
98
107
  sampleRate = 10000
99
108
 
100
109
  # 1 s cosine ramp:
101
- data_cosine = (((1 - np.cos(np.arange(sampleRate, dtype=np.float64)
102
- * 2*np.pi/sampleRate)) + 1) - 1)/2 # create raised cosine waveform
110
+ data_cosine = (
111
+ (
112
+ (
113
+ 1
114
+ - np.cos(
115
+ np.arange(sampleRate, dtype=np.float64) * 2 * np.pi / sampleRate
116
+ )
117
+ )
118
+ + 1
119
+ )
120
+ - 1
121
+ ) / 2 # create raised cosine waveform
103
122
 
104
123
  # 1 ms cosine ramp:
105
124
  rise_and_fall = (
106
- ((1 - np.cos(np.arange(sampleRate*0.001, dtype=np.float64)*2*np.pi/10))+1)-1)/2
125
+ (
126
+ (
127
+ 1
128
+ - np.cos(
129
+ np.arange(sampleRate * 0.001, dtype=np.float64) * 2 * np.pi / 10
130
+ )
131
+ )
132
+ + 1
133
+ )
134
+ - 1
135
+ ) / 2
107
136
  half_length = rise_and_fall.size / 2
108
137
 
109
138
  # pulses with cosine ramp:
110
- pulse_2ms = np.concatenate((rise_and_fall[:half_length], np.ones(
111
- (int(sampleRate*0.001),)), rise_and_fall[half_length:]))
112
- pulse_5ms = np.concatenate((rise_and_fall[:half_length], np.ones(
113
- (int(sampleRate*0.004),)), rise_and_fall[half_length:]))
114
- pulse_10ms = np.concatenate((rise_and_fall[:half_length], np.ones(
115
- (int(sampleRate*0.009),)), rise_and_fall[half_length:]))
139
+ pulse_2ms = np.concatenate(
140
+ (
141
+ rise_and_fall[:half_length],
142
+ np.ones((int(sampleRate * 0.001),)),
143
+ rise_and_fall[half_length:],
144
+ )
145
+ )
146
+ pulse_5ms = np.concatenate(
147
+ (
148
+ rise_and_fall[:half_length],
149
+ np.ones((int(sampleRate * 0.004),)),
150
+ rise_and_fall[half_length:],
151
+ )
152
+ )
153
+ pulse_10ms = np.concatenate(
154
+ (
155
+ rise_and_fall[:half_length],
156
+ np.ones((int(sampleRate * 0.009),)),
157
+ rise_and_fall[half_length:],
158
+ )
159
+ )
116
160
 
117
161
  data_2ms_10Hz = np.zeros((sampleRate,), dtype=np.float64)
118
162
 
119
163
  for i in range(0, 10):
120
164
  interval = sampleRate / 10
121
- data_2ms_10Hz[i*interval:i*interval+pulse_2ms.size] = pulse_2ms
165
+ data_2ms_10Hz[i * interval : i * interval + pulse_2ms.size] = pulse_2ms
122
166
 
123
167
  data_5ms = np.zeros((sampleRate,), dtype=np.float64)
124
- data_5ms[:pulse_5ms.size] = pulse_5ms
168
+ data_5ms[: pulse_5ms.size] = pulse_5ms
125
169
 
126
170
  data_10ms = np.zeros((sampleRate,), dtype=np.float64)
127
- data_10ms[:pulse_10ms.size] = pulse_10ms
171
+ data_10ms[: pulse_10ms.size] = pulse_10ms
128
172
 
129
- data_10s = np.zeros((sampleRate*10,), dtype=np.float64)
173
+ data_10s = np.zeros((sampleRate * 10,), dtype=np.float64)
130
174
  data_10s[:-2] = 1
131
175
 
132
176
  # %% for experiment
@@ -138,8 +182,8 @@ def optotagging(mouseID, operation_mode='experiment', level_list=[1.15, 1.28, 1.
138
182
  condition_list = [2, 3]
139
183
  waveforms = [data_2ms_10Hz, data_5ms, data_10ms, data_cosine]
140
184
 
141
- opto_levels = np.array(level_list*numRepeats*len(condition_list)) # BLUE
142
- opto_conditions = condition_list*numRepeats*len(level_list)
185
+ opto_levels = np.array(level_list * numRepeats * len(condition_list)) # BLUE
186
+ opto_conditions = condition_list * numRepeats * len(level_list)
143
187
  opto_conditions = np.sort(opto_conditions)
144
188
  opto_isis = np.random.random(opto_levels.shape) * isi_rand + isi
145
189
 
@@ -151,7 +195,7 @@ def optotagging(mouseID, operation_mode='experiment', level_list=[1.15, 1.28, 1.
151
195
 
152
196
  # %% for testing
153
197
 
154
- if operation_mode == 'test_levels':
198
+ if operation_mode == "test_levels":
155
199
  isi = 2.0
156
200
  isi_rand = 0.0
157
201
 
@@ -160,60 +204,69 @@ def optotagging(mouseID, operation_mode='experiment', level_list=[1.15, 1.28, 1.
160
204
  condition_list = [0]
161
205
  waveforms = [data_10s, data_10s]
162
206
 
163
- opto_levels = np.array(level_list*numRepeats *
164
- len(condition_list)) # BLUE
165
- opto_conditions = condition_list*numRepeats*len(level_list)
207
+ opto_levels = np.array(level_list * numRepeats * len(condition_list)) # BLUE
208
+ opto_conditions = condition_list * numRepeats * len(level_list)
166
209
  opto_conditions = np.sort(opto_conditions)
167
210
  opto_isis = np.random.random(opto_levels.shape) * isi_rand + isi
168
211
 
169
- elif operation_mode == 'pretest':
212
+ elif operation_mode == "pretest":
170
213
  numRepeats = 1
171
214
 
172
215
  condition_list = [0]
173
- data_2s = data_10s[-sampleRate*2:]
216
+ data_2s = data_10s[-sampleRate * 2 :]
174
217
  waveforms = [data_2s]
175
218
 
176
- opto_levels = np.array(level_list*numRepeats *
177
- len(condition_list)) # BLUE
178
- opto_conditions = condition_list*numRepeats*len(level_list)
219
+ opto_levels = np.array(level_list * numRepeats * len(condition_list)) # BLUE
220
+ opto_conditions = condition_list * numRepeats * len(level_list)
179
221
  opto_conditions = np.sort(opto_conditions)
180
- opto_isis = [1]*len(opto_conditions)
222
+ opto_isis = [1] * len(opto_conditions)
181
223
  # %%
182
224
 
183
225
  outputDirectory = agent.OUTPUT_DIR
184
- fileDate = str(datetime.datetime.now()).replace(':', '').replace(
185
- '.', '').replace('-', '').replace(' ', '')[2:14]
186
- fileName = outputDirectory + "/" + fileDate + '_'+mouseID + '.opto.pkl'
187
-
188
- print('saving info to: ' + fileName)
189
- fl = open(fileName, 'wb')
226
+ fileDate = (
227
+ str(datetime.datetime.now())
228
+ .replace(":", "")
229
+ .replace(".", "")
230
+ .replace("-", "")
231
+ .replace(" ", "")[2:14]
232
+ )
233
+ fileName = outputDirectory + "/" + fileDate + "_" + mouseID + ".opto.pkl"
234
+
235
+ print("saving info to: " + fileName)
236
+ fl = open(fileName, "wb")
190
237
  output = {}
191
238
 
192
- output['opto_levels'] = opto_levels
193
- output['opto_conditions'] = opto_conditions
194
- output['opto_ISIs'] = opto_isis
195
- output['opto_waveforms'] = waveforms
239
+ output["opto_levels"] = opto_levels
240
+ output["opto_conditions"] = opto_conditions
241
+ output["opto_ISIs"] = opto_isis
242
+ output["opto_waveforms"] = waveforms
196
243
 
197
244
  pkl.dump(output, fl)
198
245
  fl.close()
199
- print('saved.')
246
+ print("saved.")
200
247
 
201
248
  # %%
202
- run_optotagging(opto_levels, opto_conditions,
203
- waveforms, opto_isis, float(sampleRate))
249
+ run_optotagging(
250
+ opto_levels, opto_conditions, waveforms, opto_isis, float(sampleRate)
251
+ )
204
252
 
205
253
 
206
254
  # %%
207
255
  if __name__ == "__main__":
208
- import json
209
256
  import argparse
257
+ import json
210
258
 
211
259
  parser = argparse.ArgumentParser()
212
- parser.add_argument('json_params', type=str, )
260
+ parser.add_argument(
261
+ "json_params",
262
+ type=str,
263
+ )
213
264
  args, _ = parser.parse_known_args()
214
265
 
215
- with open(args.json_params, 'r', ) as f:
266
+ with open(
267
+ args.json_params,
268
+ ) as f:
216
269
  json_params = json.load(f)
217
270
 
218
- logging.info('Optotagging with params: %s' % json_params)
271
+ logging.info("Optotagging with params: %s" % json_params)
219
272
  optotagging(**json_params)
@@ -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 BarcodeSession(enum.Enum):
49
30
 
50
31
  class BarcodeMixin:
51
32
  """Provides project-specific methods and attributes, mainly related to camstim scripts."""
52
-
33
+
53
34
  workflow: BarcodeSession
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 BarcodeMixin:
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 BarcodeMixin:
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_barcode_session'] = str(self.workflow)
76
+ self.mouse.state["last_session"] = self.session.id
77
+ self.mouse.state["last_barcode_session"] = str(self.workflow)
97
78
  if self.mouse == 366122:
98
79
  return
99
80
  match self.workflow:
100
81
  case BarcodeSession.PRETEST:
101
82
  return
102
83
  case BarcodeSession.HAB:
103
- self.session.project.state['latest_hab'] = self.session.id
84
+ self.session.project.state["latest_hab"] = self.session.id
104
85
  case BarcodeSession.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'barcode_{self.workflow.name.lower()}').info(f"Started session {self.mouse.mtrain.stage['name']}")
97
+
98
+ np_logging.web(f"barcode_{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'barcode_{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"barcode_{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: BarcodeSession, mouse: np_session.Mouse) -> None:
158
- for workflow in ('hab', 'ephys'):
149
+
150
+
151
+ def validate_selected_workflow(
152
+ session: BarcodeSession, 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(BarcodeMixin, 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'barcode_{experiment.workflow.name.lower()}').info(f"{experiment} created")
215
-
216
- return experiment
213
+ np_logging.web(f"barcode_{experiment.workflow.name.lower()}").info(
214
+ f"{experiment} created"
215
+ )
217
216
 
217
+ return experiment
@@ -1,2 +1,2 @@
1
- from .main_loop_pilot import new_experiment, Hab, Ephys, validate_selected_workflow
2
1
  from .loop_workflow_widget import loop_workflow_widget
2
+ from .main_loop_pilot import Ephys, Hab, new_experiment, validate_selected_workflow
@@ -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, "r") as f:
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['sweep_frames']
60
- del self_dict['sweep_order']
61
- self_dict['stim'] = str(self_dict['stim'])
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"""