np-workflows 1.6.89__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 +7 -0
  2. np_workflows/assets/images/logo_np_hab.png +0 -0
  3. np_workflows/assets/images/logo_np_vis.png +0 -0
  4. np_workflows/experiments/__init__.py +1 -0
  5. np_workflows/experiments/dynamic_routing/__init__.py +2 -0
  6. np_workflows/experiments/dynamic_routing/main.py +117 -0
  7. np_workflows/experiments/dynamic_routing/widgets.py +82 -0
  8. np_workflows/experiments/openscope_P3/P3_workflow_widget.py +83 -0
  9. np_workflows/experiments/openscope_P3/__init__.py +2 -0
  10. np_workflows/experiments/openscope_P3/main_P3_pilot.py +217 -0
  11. np_workflows/experiments/openscope_barcode/__init__.py +2 -0
  12. np_workflows/experiments/openscope_barcode/barcode_workflow_widget.py +83 -0
  13. np_workflows/experiments/openscope_barcode/camstim_scripts/barcode_mapping_script.py +138 -0
  14. np_workflows/experiments/openscope_barcode/camstim_scripts/barcode_opto_script.py +219 -0
  15. np_workflows/experiments/openscope_barcode/main_barcode_pilot.py +217 -0
  16. np_workflows/experiments/openscope_loop/__init__.py +2 -0
  17. np_workflows/experiments/openscope_loop/camstim_scripts/barcode_mapping_script.py +138 -0
  18. np_workflows/experiments/openscope_loop/camstim_scripts/barcode_opto_script.py +219 -0
  19. np_workflows/experiments/openscope_loop/loop_workflow_widget.py +83 -0
  20. np_workflows/experiments/openscope_loop/main_loop_pilot.py +217 -0
  21. np_workflows/experiments/openscope_psycode/__init__.py +2 -0
  22. np_workflows/experiments/openscope_psycode/main_psycode_pilot.py +217 -0
  23. np_workflows/experiments/openscope_psycode/psycode_workflow_widget.py +83 -0
  24. np_workflows/experiments/openscope_v2/__init__.py +2 -0
  25. np_workflows/experiments/openscope_v2/main_v2_pilot.py +217 -0
  26. np_workflows/experiments/openscope_v2/v2_workflow_widget.py +83 -0
  27. np_workflows/experiments/openscope_vippo/__init__.py +2 -0
  28. np_workflows/experiments/openscope_vippo/main_vippo_pilot.py +217 -0
  29. np_workflows/experiments/openscope_vippo/vippo_workflow_widget.py +83 -0
  30. np_workflows/experiments/task_trained_network/__init__.py +2 -0
  31. np_workflows/experiments/task_trained_network/camstim_scripts/make_tt_stims.py +23 -0
  32. np_workflows/experiments/task_trained_network/camstim_scripts/oct22_tt_stim_script.py +69 -0
  33. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_00.stim +5 -0
  34. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_01.stim +5 -0
  35. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_02.stim +5 -0
  36. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_03.stim +5 -0
  37. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_04.stim +5 -0
  38. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_05.stim +5 -0
  39. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_06.stim +5 -0
  40. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_07.stim +5 -0
  41. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_08.stim +5 -0
  42. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_09.stim +5 -0
  43. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_10.stim +5 -0
  44. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_11.stim +5 -0
  45. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_12.stim +5 -0
  46. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_13.stim +5 -0
  47. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_14.stim +5 -0
  48. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_15.stim +5 -0
  49. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_16.stim +5 -0
  50. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_17.stim +5 -0
  51. np_workflows/experiments/task_trained_network/camstim_scripts/stims/densely_annotated_18.stim +5 -0
  52. np_workflows/experiments/task_trained_network/camstim_scripts/stims/flash_250ms.stim +20 -0
  53. np_workflows/experiments/task_trained_network/camstim_scripts/stims/gabor_20_deg_250ms.stim +30 -0
  54. np_workflows/experiments/task_trained_network/camstim_scripts/stims/old_stim.stim +5 -0
  55. np_workflows/experiments/task_trained_network/camstim_scripts/stims/shuffle_reversed.stim +5 -0
  56. np_workflows/experiments/task_trained_network/camstim_scripts/stims/shuffle_reversed_1st.stim +5 -0
  57. np_workflows/experiments/task_trained_network/camstim_scripts/stims/shuffle_reversed_2nd.stim +5 -0
  58. np_workflows/experiments/task_trained_network/camstim_scripts/ttn_main_script.py +130 -0
  59. np_workflows/experiments/task_trained_network/camstim_scripts/ttn_mapping_script.py +138 -0
  60. np_workflows/experiments/task_trained_network/camstim_scripts/ttn_opto_script.py +219 -0
  61. np_workflows/experiments/task_trained_network/main_ttn_pilot.py +263 -0
  62. np_workflows/experiments/task_trained_network/ttn_session_widget.py +83 -0
  63. np_workflows/experiments/task_trained_network/ttn_stim_config.py +213 -0
  64. np_workflows/experiments/templeton/__init__.py +2 -0
  65. np_workflows/experiments/templeton/main.py +105 -0
  66. np_workflows/experiments/templeton/widgets.py +82 -0
  67. np_workflows/shared/__init__.py +3 -0
  68. np_workflows/shared/base_experiments.py +826 -0
  69. np_workflows/shared/camstim_scripts/flash_250ms.stim +20 -0
  70. np_workflows/shared/camstim_scripts/gabor_20_deg_250ms.stim +30 -0
  71. np_workflows/shared/npxc.py +187 -0
  72. np_workflows/shared/widgets.py +705 -0
  73. np_workflows-1.6.89.dist-info/METADATA +85 -0
  74. np_workflows-1.6.89.dist-info/RECORD +76 -0
  75. np_workflows-1.6.89.dist-info/WHEEL +4 -0
  76. np_workflows-1.6.89.dist-info/entry_points.txt +4 -0
@@ -0,0 +1,20 @@
1
+ stimulus = Stimulus(visual.GratingStim(window,
2
+ pos = (0, 0),
3
+ units = 'deg',
4
+ size = (300, 300),
5
+ mask = "None",
6
+ texRes = 256,
7
+ sf = 0,
8
+ ),
9
+ sweep_params = {
10
+ 'Contrast': ([0.8], 0),
11
+ 'Color': ([-1, 1], 1)
12
+ },
13
+ sweep_length = 0.25,
14
+ start_time = 0.0,
15
+ blank_length = 1.75,
16
+ blank_sweeps = 0,
17
+ runs = 75,
18
+ shuffle = True,
19
+ save_sweep_table = True,
20
+ )
@@ -0,0 +1,30 @@
1
+ x = np.arange(-40,45,10)
2
+ y = np.arange(-40,45,10)
3
+ position = []
4
+ for i in x:
5
+ for j in y:
6
+ position.append([i,j])
7
+
8
+
9
+ stimulus = Stimulus(visual.GratingStim(window,
10
+ units='deg',
11
+ size=20,
12
+ mask="circle",
13
+ texRes=256,
14
+ sf=0.1,
15
+ ),
16
+ sweep_params={
17
+ 'Pos':(position, 0),
18
+ 'Contrast': ([0.8], 4),
19
+ 'TF': ([4.0], 1),
20
+ 'SF': ([0.08], 2),
21
+ 'Ori': ([0,45,90], 3),
22
+ },
23
+ sweep_length=0.25,
24
+ start_time=0.0,
25
+ blank_length=0.0,
26
+ blank_sweeps=0,
27
+ runs=15,
28
+ shuffle=True,
29
+ save_sweep_table=True,
30
+ )
@@ -0,0 +1,187 @@
1
+ import contextlib
2
+ import datetime
3
+ import inspect
4
+ import pathlib
5
+ import shutil
6
+ import sys
7
+ import time
8
+ from typing import Any, Generator, Sequence, Type
9
+ import zlib
10
+
11
+ import fabric
12
+ import np_config
13
+ import np_logging
14
+ import np_session
15
+ from np_services import Initializable, Testable, TestError, Finalizable, Service
16
+ from np_services import Sync, VideoMVR, ImageMVR, Cam3d, ScriptCamstim, OpenEphys
17
+ import np_services
18
+ from np_config import Rig
19
+
20
+ logger = np_logging.getLogger(__name__)
21
+
22
+ # Assign default values to global variables so they can be imported elsewhere
23
+ # experiment: Experiment | str = ''
24
+ operator: np_session.User | str = ""
25
+ mouse: np_session.Mouse | str = ""
26
+ is_mouse_in_lims: bool | None = None
27
+ session: np_session.Session | str | int = ""
28
+
29
+ # experiments: tuple[Type[Experiment], ...] = (
30
+ # classes.Pretest,
31
+ # classes.NpUltra,
32
+ # ) # TODO plug-in experiments
33
+
34
+ RIG = np_config.Rig()
35
+ CONFIG = RIG.config
36
+
37
+ lims_user_ids: tuple[str, ...] = tuple(
38
+ sorted(
39
+ CONFIG.get('lims_user_ids',
40
+ [
41
+ "hannah.belski",
42
+ "hannah.cabasco",
43
+ "ryan.gillis",
44
+ "henry.loeffler",
45
+ "corbettb",
46
+ "ben.hardcastle",
47
+ "samg",
48
+ "ethan.mcbride",
49
+ "jackie.kuyat",
50
+ "andrew.shelton",
51
+ ]
52
+ )
53
+ )
54
+ )
55
+
56
+ default_mouse_id: int = int(CONFIG.get('default_mouse_id', 366122))
57
+
58
+
59
+ def get_operators() -> list[str]:
60
+ return list(lims_user_ids)
61
+
62
+
63
+ def print_countdown_timer(seconds: int | float | datetime.timedelta = 0, **kwargs):
64
+ """Block execution for a given number of seconds (or any timedelta kwargs), printing a countdown timer to the console."""
65
+ if isinstance(seconds, datetime.timedelta):
66
+ wait = seconds
67
+ else:
68
+ wait = datetime.timedelta(seconds=seconds, **kwargs)
69
+ time_0: float = time.time()
70
+ time_remaining = lambda: datetime.timedelta(
71
+ seconds=wait.total_seconds() - (time.time() - time_0)
72
+ )
73
+ while time_remaining().total_seconds() > 0:
74
+ print(f"Waiting {wait} \t{time_remaining()}", end="\r", flush=True)
75
+ time.sleep(0.1)
76
+
77
+ def photodoc(img_name: str) -> pathlib.Path:
78
+ """Capture image with `label` appended to filename, and return the filepath.
79
+
80
+ If multiple images are captured, only the last will remain in the Imager.data_files list.
81
+ """
82
+ if RIG.idx == 0:
83
+ from np_services import Cam3d as ImageCamera
84
+ else:
85
+ from np_services import ImageMVR as ImageCamera
86
+ from np_services import NewScaleCoordinateRecorder
87
+
88
+ ImageCamera.label = img_name
89
+ if isinstance(ImageCamera, Initializable) and not getattr(ImageCamera, 'initialization', None):
90
+ ImageCamera.initialize()
91
+
92
+ ImageCamera.start()
93
+
94
+ if isinstance(ImageCamera, Finalizable):
95
+ ImageCamera.finalize()
96
+
97
+ if isinstance(NewScaleCoordinateRecorder, Initializable) and not getattr(NewScaleCoordinateRecorder, 'initialization', None):
98
+ NewScaleCoordinateRecorder.initialize()
99
+ NewScaleCoordinateRecorder.label = img_name
100
+ NewScaleCoordinateRecorder.start()
101
+
102
+ # remove all but latest file with the current label
103
+ if img_name and ImageCamera.data_files:
104
+ views = 2 if ImageCamera.__name__ == 'Cam3d' else 1
105
+ def files_with_label():
106
+ return sorted([_ for _ in ImageCamera.data_files if img_name in _.name])
107
+ while len(files_with_label()) > views:
108
+ ImageCamera.data_files.remove(files_with_label()[0])
109
+
110
+ return ImageCamera.data_files[-1]
111
+
112
+ def copy_files(services: Sequence[Service], session_folder: pathlib.Path):
113
+ """Copy files from raw data storage to session folder for all services."""
114
+ password = input(f'Enter password for svc_neuropix:')
115
+ for service in services:
116
+ match service.__class__.__name__:
117
+ case "OpenEphys" | "open_ephys":
118
+ continue # copy ephys after other files
119
+ case _:
120
+ with contextlib.suppress(AttributeError):
121
+ files = service.data_files or service.get_latest_data('*')
122
+ if not files:
123
+ continue
124
+ files = set(files)
125
+ print(files)
126
+ for file in files:
127
+ shutil.copy2(file, session_folder)
128
+
129
+ password = np_config.fetch('/logins')['svc_neuropix']['password']
130
+ ssh = fabric.Connection(host=np_services.OpenEphys.host, user='svc_neuropix', connect_kwargs=dict(password=password))
131
+ for ephys_folder in np_services.OpenEphys.data_files:
132
+
133
+ with contextlib.suppress(Exception):
134
+ with ssh:
135
+ ssh.run(
136
+ f'robocopy "{ephys_folder}" "{session_folder / ephys_folder.name}" /j /s /xo'
137
+ # /j unbuffered, /s incl non-empty subdirs, /xo exclude src files older than dest
138
+ )
139
+
140
+
141
+ import warnings
142
+
143
+ def hide_warning_lines(msg:str,category:str,*args,**kwargs):
144
+ print("\n{}: {}\n".format(category.__name__, msg))
145
+ warnings.showwarning = hide_warning_lines
146
+
147
+ import IPython
148
+ def toggle_tracebacks() -> Generator[None, None, None]:
149
+ if ipython := IPython.get_ipython():
150
+ show_traceback = ipython.showtraceback
151
+
152
+ def hide_traceback(exc_tuple=None, filename=None, tb_offset=None,
153
+ exception_only=False, running_compiled_code=False):
154
+ etype, value, tb = sys.exc_info()
155
+ return ipython._showtraceback(etype, value, ipython.InteractiveTB.get_exception_only(etype, value))
156
+
157
+ hidden = True
158
+ while True:
159
+ ipython.showtraceback = hide_traceback if hidden else show_traceback
160
+ hidden = yield
161
+ else:
162
+ raise RuntimeError("Not in IPython")
163
+
164
+ with contextlib.suppress(RuntimeError):
165
+ toggle_tb = toggle_tracebacks()
166
+
167
+ toggle_tb.send(None)
168
+ def show_tracebacks():
169
+ toggle_tb.send(False)
170
+ def hide_tracebacks():
171
+ toggle_tb.send(True)
172
+
173
+ def now() -> str:
174
+ return np_services.utils.normalize_time(time.time())
175
+
176
+ def validate_or_overwrite(validate: str | pathlib.Path, src: str | pathlib.Path):
177
+ "Checksum validate against `src`, (over)write `validate` as `src` if different."
178
+ validate, src = pathlib.Path(validate), pathlib.Path(src)
179
+ def copy():
180
+ logger.debug("Copying %s to %s", src, validate)
181
+ shutil.copy2(src, validate)
182
+ while (
183
+ validate.exists() == False
184
+ or (v := zlib.crc32(validate.read_bytes())) != (c := zlib.crc32(pathlib.Path(src).read_bytes()))
185
+ ):
186
+ copy()
187
+ logger.debug("Validated %s CRC32: %08X", validate, (v & 0xFFFFFFFF) )