12
12
13
13
schema = dj .schema ()
14
14
15
+ context = locals ()
16
+
17
+ table_classes = (dj .Manual , dj .Lookup , dj .Imported , dj .Computed )
18
+
15
19
16
20
def activate (ephys_schema_name , probe_schema_name = None , create_schema = True , create_tables = True , add_objects = None ):
17
21
assert isinstance (add_objects , Mapping )
18
22
19
23
upstream_tables = ("Session" , "SkullReference" )
20
- try :
21
- raise RuntimeError ("Table %s is required for module ephys" % next (
22
- name for name in upstream_tables
23
- if not isinstance (add_objects .get (name , None ), (dj .Manual , dj .Lookup , dj .Imported , dj .Computed , dj .user_tables .OrderedClass ))))
24
- except StopIteration :
25
- pass # all ok
24
+ for name in upstream_tables :
25
+ assert name in add_objects , "Upstream table %s is required in ephys.activate(add_objects=...)" % name
26
+ table = add_objects [name ]
27
+ if inspect .isclass (table ):
28
+ table = table ()
29
+ assert isinstance (table , table_classes ), "Upstream table %s must be a DataJoint table " \
30
+ "object in ephys.activate(add_objects=...)" % name
26
31
27
32
required_functions = ("get_neuropixels_data_directory" , "get_paramset_idx" , "get_kilosort_output_directory" )
28
- try :
29
- raise RuntimeError ("Function %s is required for module ephys" % next (
30
- name for name in required_functions
31
- if not inspect .isfunction (add_objects .get (name , None ))))
32
- except StopIteration :
33
- pass # all ok
34
-
35
- if not probe .schema .database :
33
+ for name in required_functions :
34
+ assert name in add_objects , "Functions %s is required in ephys.activate(add_objects=...)" % name
35
+ assert inspect .isfunction (add_objects [name ]), "%s must be a function in ephys.activate(add_objects=...)" % name
36
+ context .update (** {name : add_objects [name ]})
37
+
38
+ # activate
39
+ if not probe .schema .is_activated :
36
40
probe .schema .activate (probe_schema_name or ephys_schema_name ,
37
41
create_schema = create_schema , create_tables = create_tables )
38
42
39
43
schema .activate (ephys_schema_name , create_schema = create_schema ,
40
44
create_tables = create_tables , add_objects = add_objects )
41
45
42
46
43
- # REQUIREMENTS: The workflow module must define these functions ---------------
47
+ # -------------- Functions required by the elements-ephys ---------------
44
48
45
49
46
50
def get_neuropixels_data_directory (probe_insertion_key : dict ) -> str :
@@ -73,8 +77,7 @@ def get_paramset_idx(ephys_rec_key: dict) -> int:
73
77
raise NotImplementedError ('Workflow module should define function: get_paramset_idx' )
74
78
75
79
76
- # ===================================== Probe Insertion =====================================
77
-
80
+ # ----------------------------- Table declarations ----------------------
78
81
79
82
@schema
80
83
class ProbeInsertion (dj .Manual ): # (acute)
@@ -86,9 +89,6 @@ class ProbeInsertion(dj.Manual): # (acute)
86
89
"""
87
90
88
91
89
- # ===================================== Insertion Location =====================================
90
-
91
-
92
92
@schema
93
93
class InsertionLocation (dj .Manual ):
94
94
@@ -105,8 +105,6 @@ class InsertionLocation(dj.Manual):
105
105
"""
106
106
107
107
108
- # ===================================== Ephys Recording =====================================
109
-
110
108
@schema
111
109
class EphysRecording (dj .Imported ):
112
110
definition = """
@@ -145,20 +143,13 @@ def make(self, key):
145
143
e_config = {'electrode_config_hash' : ec_hash }
146
144
147
145
# ---- make new ElectrodeConfig if needed ----
148
- if not ( probe .ElectrodeConfig & e_config ) :
146
+ if not probe .ElectrodeConfig & e_config :
149
147
probe .ElectrodeConfig .insert1 ({** e_config , ** probe_type , 'electrode_config_name' : ec_name })
150
148
probe .ElectrodeConfig .Electrode .insert ({** e_config , ** m } for m in eg_members )
151
149
152
150
self .insert1 ({** key , ** e_config , 'sampling_rate' : neuropixels_meta .meta ['imSampRate' ]})
153
151
154
152
155
- # ===========================================================================================
156
- # ================================= NON-CONFIGURABLE COMPONENTS =============================
157
- # ===========================================================================================
158
-
159
-
160
- # ===================================== Ephys LFP =====================================
161
-
162
153
@schema
163
154
class LFP (dj .Imported ):
164
155
definition = """
@@ -202,12 +193,12 @@ def make(self, key):
202
193
203
194
chn_lfp = list (zip (electrodes , lfp ))
204
195
skip_chn_counts = 9
205
- self .Electrode .insert (({** key , ** electrode , 'lfp' : d }
206
- for electrode , d in chn_lfp [- 1 ::- skip_chn_counts ]), ignore_extra_fields = True )
196
+ self .Electrode ().insert ((
197
+ {** key , ** electrode , 'lfp' : d }
198
+ for electrode , d in chn_lfp [- 1 ::- skip_chn_counts ]), ignore_extra_fields = True )
207
199
208
200
209
- # ===================================== Clustering =====================================
210
-
201
+ # ------------ Clustering --------------
211
202
212
203
@schema
213
204
class ClusteringMethod (dj .Lookup ):
@@ -376,14 +367,13 @@ class Electrode(dj.Part):
376
367
377
368
@property
378
369
def key_source (self ):
379
- return Clustering
370
+ return Clustering ()
380
371
381
372
def make (self , key ):
382
373
units = {u ['unit' ]: u for u in (Clustering .Unit & key ).fetch (as_dict = True , order_by = 'unit' )}
383
374
384
375
neuropixels_dir = EphysRecording ._get_neuropixels_data_directory (key )
385
376
meta_filepath = next (pathlib .Path (neuropixels_dir ).glob ('*.ap.meta' ))
386
- neuropixels_meta = neuropixels .NeuropixelsMeta (meta_filepath )
387
377
388
378
ks_dir = ClusteringTask ._get_ks_data_dir (key )
389
379
ks = kilosort .Kilosort (ks_dir )
@@ -451,7 +441,7 @@ def key_source(self):
451
441
def make (self , key ):
452
442
pass
453
443
454
- # ========================== HELPER FUNCTIONS =======================
444
+ # ---------------- HELPER FUNCTIONS ----------------
455
445
456
446
457
447
def get_neuropixels_chn2electrode_map (ephys_recording_key ):
@@ -472,7 +462,7 @@ def get_neuropixels_chn2electrode_map(ephys_recording_key):
472
462
473
463
def dict_to_uuid (key ):
474
464
"""
475
- Given a dictionary `key`, returns a hash string
465
+ Given a dictionary `key`, returns a hash string as UUID
476
466
"""
477
467
hashed = hashlib .md5 ()
478
468
for k , v in sorted (key .items ()):
0 commit comments