Skip to content

Commit dadda0d

Browse files
authored
Merge pull request #4 from dimitri-yatsenko/main
ephys.activate inserts required functions into the module namespace
2 parents 1cc5119 + 1f732d3 commit dadda0d

File tree

1 file changed

+28
-38
lines changed

1 file changed

+28
-38
lines changed

elements_ephys/ephys.py

Lines changed: 28 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,35 +12,39 @@
1212

1313
schema = dj.schema()
1414

15+
context = locals()
16+
17+
table_classes = (dj.Manual, dj.Lookup, dj.Imported, dj.Computed)
18+
1519

1620
def activate(ephys_schema_name, probe_schema_name=None, create_schema=True, create_tables=True, add_objects=None):
1721
assert isinstance(add_objects, Mapping)
1822

1923
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
2631

2732
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:
3640
probe.schema.activate(probe_schema_name or ephys_schema_name,
3741
create_schema=create_schema, create_tables=create_tables)
3842

3943
schema.activate(ephys_schema_name, create_schema=create_schema,
4044
create_tables=create_tables, add_objects=add_objects)
4145

4246

43-
# REQUIREMENTS: The workflow module must define these functions ---------------
47+
# -------------- Functions required by the elements-ephys ---------------
4448

4549

4650
def get_neuropixels_data_directory(probe_insertion_key: dict) -> str:
@@ -73,8 +77,7 @@ def get_paramset_idx(ephys_rec_key: dict) -> int:
7377
raise NotImplementedError('Workflow module should define function: get_paramset_idx')
7478

7579

76-
# ===================================== Probe Insertion =====================================
77-
80+
# ----------------------------- Table declarations ----------------------
7881

7982
@schema
8083
class ProbeInsertion(dj.Manual): # (acute)
@@ -86,9 +89,6 @@ class ProbeInsertion(dj.Manual): # (acute)
8689
"""
8790

8891

89-
# ===================================== Insertion Location =====================================
90-
91-
9292
@schema
9393
class InsertionLocation(dj.Manual):
9494

@@ -105,8 +105,6 @@ class InsertionLocation(dj.Manual):
105105
"""
106106

107107

108-
# ===================================== Ephys Recording =====================================
109-
110108
@schema
111109
class EphysRecording(dj.Imported):
112110
definition = """
@@ -145,20 +143,13 @@ def make(self, key):
145143
e_config = {'electrode_config_hash': ec_hash}
146144

147145
# ---- make new ElectrodeConfig if needed ----
148-
if not (probe.ElectrodeConfig & e_config):
146+
if not probe.ElectrodeConfig & e_config:
149147
probe.ElectrodeConfig.insert1({**e_config, **probe_type, 'electrode_config_name': ec_name})
150148
probe.ElectrodeConfig.Electrode.insert({**e_config, **m} for m in eg_members)
151149

152150
self.insert1({**key, **e_config, 'sampling_rate': neuropixels_meta.meta['imSampRate']})
153151

154152

155-
# ===========================================================================================
156-
# ================================= NON-CONFIGURABLE COMPONENTS =============================
157-
# ===========================================================================================
158-
159-
160-
# ===================================== Ephys LFP =====================================
161-
162153
@schema
163154
class LFP(dj.Imported):
164155
definition = """
@@ -202,12 +193,12 @@ def make(self, key):
202193

203194
chn_lfp = list(zip(electrodes, lfp))
204195
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)
207199

208200

209-
# ===================================== Clustering =====================================
210-
201+
# ------------ Clustering --------------
211202

212203
@schema
213204
class ClusteringMethod(dj.Lookup):
@@ -376,14 +367,13 @@ class Electrode(dj.Part):
376367

377368
@property
378369
def key_source(self):
379-
return Clustering
370+
return Clustering()
380371

381372
def make(self, key):
382373
units = {u['unit']: u for u in (Clustering.Unit & key).fetch(as_dict=True, order_by='unit')}
383374

384375
neuropixels_dir = EphysRecording._get_neuropixels_data_directory(key)
385376
meta_filepath = next(pathlib.Path(neuropixels_dir).glob('*.ap.meta'))
386-
neuropixels_meta = neuropixels.NeuropixelsMeta(meta_filepath)
387377

388378
ks_dir = ClusteringTask._get_ks_data_dir(key)
389379
ks = kilosort.Kilosort(ks_dir)
@@ -451,7 +441,7 @@ def key_source(self):
451441
def make(self, key):
452442
pass
453443

454-
# ========================== HELPER FUNCTIONS =======================
444+
# ---------------- HELPER FUNCTIONS ----------------
455445

456446

457447
def get_neuropixels_chn2electrode_map(ephys_recording_key):
@@ -472,7 +462,7 @@ def get_neuropixels_chn2electrode_map(ephys_recording_key):
472462

473463
def dict_to_uuid(key):
474464
"""
475-
Given a dictionary `key`, returns a hash string
465+
Given a dictionary `key`, returns a hash string as UUID
476466
"""
477467
hashed = hashlib.md5()
478468
for k, v in sorted(key.items()):

0 commit comments

Comments
 (0)