Skip to content

Commit a7b2abb

Browse files
committed
Merge remote-tracking branch 'origin/convert_to_nwb' into convert_to_nwb
2 parents acdb5f9 + c200699 commit a7b2abb

File tree

5 files changed

+40
-41
lines changed

5 files changed

+40
-41
lines changed

element_array_ephys/__init__.py

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,2 @@
1-
import datajoint as dj
2-
import logging
3-
import os
4-
5-
6-
dj.config['enable_python_native_blobs'] = True
7-
8-
9-
def get_logger(name):
10-
log = logging.getLogger(name)
11-
log.setLevel(os.getenv('LOGLEVEL', 'INFO'))
12-
return log
13-
14-
151
# ephys_acute as default
16-
import element_array_ephys.ephys_acute as ephys
2+
import element_array_ephys.ephys_acute as ephys

element_array_ephys/ephys_acute.py

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ def activate(ephys_schema_name, probe_schema_name=None, *, create_schema=True,
5757

5858
def get_ephys_root_data_dir() -> list:
5959
"""
60-
All data paths, directories in DataJoint Elements are recommended to be
61-
stored as relative paths, with respect to some user-configured "root"
62-
directory, which varies from machine to machine (e.g. different mounted
60+
All data paths, directories in DataJoint Elements are recommended to be
61+
stored as relative paths, with respect to some user-configured "root"
62+
directory, which varies from machine to machine (e.g. different mounted
6363
drive locations)
6464
6565
get_ephys_root_data_dir() -> list
@@ -130,7 +130,9 @@ class EphysRecording(dj.Imported):
130130
---
131131
-> probe.ElectrodeConfig
132132
-> AcquisitionSoftware
133-
sampling_rate: float # (Hz)
133+
sampling_rate: float # (Hz)
134+
recording_datetime: datetime # datetime of the recording from this probe
135+
recording_duration: float # (seconds) duration of the recording from this probe
134136
"""
135137

136138
class EphysFile(dj.Part):
@@ -142,7 +144,7 @@ class EphysFile(dj.Part):
142144

143145
def make(self, key):
144146

145-
session_dir = find_full_path(get_ephys_root_data_dir(),
147+
session_dir = find_full_path(get_ephys_root_data_dir(),
146148
get_session_directory(key))
147149

148150
inserted_probe_serial_number = (ProbeInsertion * probe.Probe & key).fetch1('probe')
@@ -189,9 +191,12 @@ def make(self, key):
189191
self.insert1({**key,
190192
**generate_electrode_config(probe_type, electrode_group_members),
191193
'acq_software': acq_software,
192-
'sampling_rate': spikeglx_meta.meta['imSampRate']})
194+
'sampling_rate': spikeglx_meta.meta['imSampRate'],
195+
'recording_datetime': spikeglx_meta.recording_time,
196+
'recording_duration': (spikeglx_meta.recording_duration
197+
or spikeglx.retrieve_recording_duration(meta_filepath))})
193198

194-
root_dir = find_root_directory(get_ephys_root_data_dir(),
199+
root_dir = find_root_directory(get_ephys_root_data_dir(),
195200
meta_filepath)
196201
self.EphysFile.insert1({
197202
**key,
@@ -223,7 +228,9 @@ def make(self, key):
223228
self.insert1({**key,
224229
**generate_electrode_config(probe_type, electrode_group_members),
225230
'acq_software': acq_software,
226-
'sampling_rate': probe_data.ap_meta['sample_rate']})
231+
'sampling_rate': probe_data.ap_meta['sample_rate'],
232+
'recording_datetime': probe_data.recording_info['recording_datetimes'][0],
233+
'recording_duration': np.sum(probe_data.recording_info['recording_durations'])})
227234

228235
root_dir = find_root_directory(get_ephys_root_data_dir(),
229236
probe_data.recording_info['recording_files'][0])
@@ -294,8 +301,7 @@ def make(self, key):
294301
shank, shank_col, shank_row, _ = spikeglx_recording.apmeta.shankmap['data'][recorded_site]
295302
electrode_keys.append(probe_electrodes[(shank, shank_col, shank_row)])
296303
elif acq_software == 'Open Ephys':
297-
298-
session_dir = find_full_path(get_ephys_root_data_dir(),
304+
session_dir = find_full_path(get_ephys_root_data_dir(),
299305
get_session_directory(key))
300306

301307
loaded_oe = openephys.OpenEphys(session_dir)
@@ -457,9 +463,8 @@ class Curation(dj.Manual):
457463

458464
def create1_from_clustering_task(self, key, curation_note=''):
459465
"""
460-
A function to create a new corresponding "Curation" for a particular
461-
"ClusteringTask", which assumes that no curation was performed on the
462-
dataset
466+
A function to create a new corresponding "Curation" for a particular
467+
"ClusteringTask"
463468
"""
464469
if key not in Clustering():
465470
raise ValueError(f'No corresponding entry in Clustering available'
@@ -473,9 +478,9 @@ def create1_from_clustering_task(self, key, curation_note=''):
473478
# Synthesize curation_id
474479
curation_id = dj.U().aggr(self & key, n='ifnull(max(curation_id)+1,1)').fetch1('n')
475480
self.insert1({**key, 'curation_id': curation_id,
476-
'curation_time': creation_time,
481+
'curation_time': creation_time,
477482
'curation_output_dir': output_dir,
478-
'quality_control': is_qc,
483+
'quality_control': is_qc,
479484
'manual_curation': is_curated,
480485
'curation_note': curation_note})
481486

@@ -623,7 +628,7 @@ def yield_unit_waveforms():
623628
spikeglx_meta_filepath = get_spikeglx_meta_filepath(key)
624629
neuropixels_recording = spikeglx.SpikeGLX(spikeglx_meta_filepath.parent)
625630
elif acq_software == 'Open Ephys':
626-
session_dir = find_full_path(get_ephys_root_data_dir(),
631+
session_dir = find_full_path(get_ephys_root_data_dir(),
627632
get_session_directory(key))
628633
openephys_dataset = openephys.OpenEphys(session_dir)
629634
neuropixels_recording = openephys_dataset.probes[probe_serial_number]
@@ -670,7 +675,7 @@ def get_spikeglx_meta_filepath(ephys_recording_key):
670675
except FileNotFoundError:
671676
# if not found, search in session_dir again
672677
if not spikeglx_meta_filepath.exists():
673-
session_dir = find_full_path(get_ephys_root_data_dir(),
678+
session_dir = find_full_path(get_ephys_root_data_dir(),
674679
get_session_directory(
675680
ephys_recording_key))
676681
inserted_probe_serial_number = (ProbeInsertion * probe.Probe
@@ -709,7 +714,7 @@ def get_neuropixels_channel2electrode_map(ephys_recording_key, acq_software):
709714
for recorded_site, (shank, shank_col, shank_row, _) in enumerate(
710715
spikeglx_meta.shankmap['data'])}
711716
elif acq_software == 'Open Ephys':
712-
session_dir = find_full_path(get_ephys_root_data_dir(),
717+
session_dir = find_full_path(get_ephys_root_data_dir(),
713718
get_session_directory(ephys_recording_key))
714719
openephys_dataset = openephys.OpenEphys(session_dir)
715720
probe_serial_number = (ProbeInsertion & ephys_recording_key).fetch1('probe')

element_array_ephys/ephys_chronic.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,9 @@ class EphysRecording(dj.Imported):
132132
---
133133
-> probe.ElectrodeConfig
134134
-> AcquisitionSoftware
135-
sampling_rate: float # (Hz)
135+
sampling_rate: float # (Hz)
136+
recording_datetime: datetime # datetime of the recording from this probe
137+
recording_duration: float # (seconds) duration of the recording from this probe
136138
"""
137139

138140
class EphysFile(dj.Part):
@@ -168,7 +170,8 @@ def make(self, key):
168170
break
169171
else:
170172
raise FileNotFoundError(
171-
'No SpikeGLX data found for probe insertion: {}'.format(key))
173+
f'No SpikeGLX data found for probe insertion: {key}' +
174+
' The probe serial number does not match.')
172175

173176
if re.search('(1.0|2.0)', spikeglx_meta.probe_model):
174177
probe_type = spikeglx_meta.probe_model
@@ -190,7 +193,10 @@ def make(self, key):
190193
self.insert1({**key,
191194
**generate_electrode_config(probe_type, electrode_group_members),
192195
'acq_software': acq_software,
193-
'sampling_rate': spikeglx_meta.meta['imSampRate']})
196+
'sampling_rate': spikeglx_meta.meta['imSampRate'],
197+
'recording_datetime': spikeglx_meta.recording_time,
198+
'recording_duration': (spikeglx_meta.recording_duration
199+
or spikeglx.retrieve_recording_duration(meta_filepath))})
194200

195201
root_dir = find_root_directory(get_ephys_root_data_dir(),
196202
meta_filepath)
@@ -224,7 +230,9 @@ def make(self, key):
224230
self.insert1({**key,
225231
**generate_electrode_config(probe_type, electrode_group_members),
226232
'acq_software': acq_software,
227-
'sampling_rate': probe_data.ap_meta['sample_rate']})
233+
'sampling_rate': probe_data.ap_meta['sample_rate'],
234+
'recording_datetime': probe_data.recording_info['recording_datetimes'][0],
235+
'recording_duration': np.sum(probe_data.recording_info['recording_durations'])})
228236

229237
root_dir = find_root_directory(get_ephys_root_data_dir(),
230238
probe_data.recording_info['recording_files'][0])

element_array_ephys/export/nwb/nwb.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
from spikeinterface import extractors
1515
from tqdm import tqdm
1616

17-
from ... import probe, ephys_acute, ephys_chronic, ephys_no_curation
17+
from ... import probe, ephys_acute
1818

1919
assert probe.schema.is_activated(), 'probe not yet activated'
2020

21-
for ephys in (ephys_acute):
21+
for ephys in (ephys_acute,):
2222
if ephys.schema.is_activated():
2323
break
2424
else:
@@ -206,7 +206,7 @@ def create_units_table(
206206
)
207207

208208
for unit in tqdm(
209-
(clustering_query @ ephys.CuratedClustering.Unit).fetch(as_dict=True),
209+
(ephys.CuratedClustering.Unit & clustering_query).fetch(as_dict=True),
210210
desc=f"creating units table for paramset {paramset_record['paramset_idx']}",
211211
):
212212

element_array_ephys/probe.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ class ElectrodeConfig(dj.Lookup):
153153
electrode_config_hash: uuid
154154
---
155155
-> ProbeType
156-
electrode_config_name: varchar(64) # user friendly name
156+
electrode_config_name: varchar(4000) # user friendly name
157157
"""
158158

159159
class Electrode(dj.Part):

0 commit comments

Comments
 (0)