Skip to content

Commit 31e46cd

Browse files
committed
Add nwb.py from run_kilosort branch
1 parent 5711a12 commit 31e46cd

File tree

1 file changed

+40
-29
lines changed
  • element_array_ephys/export/nwb

1 file changed

+40
-29
lines changed

element_array_ephys/export/nwb/nwb.py

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414
from spikeinterface import extractors
1515
from tqdm import tqdm
1616
import warnings
17-
from ... import probe, ephys_no_curation
17+
from ... import probe
18+
from ... import ephys_no_curation as ephys
1819

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

21-
assert ephys_no_curation.schema.is_activated, \
22-
"The ephys module must be activated before export."
21+
ephys_mode = os.getenv('EPHYS_MODE', dj.config['custom'].get('ephys_mode', 'acute'))
22+
if ephys_mode != 'no-curation':
23+
raise NotImplementedError('This export function is designed for the no_curation '
24+
+'schema')
2325

2426

2527
class DecimalEncoder(json.JSONEncoder):
@@ -41,14 +43,15 @@ def __init__(self, lfp_electrodes_query, chunk_length: int = 10000):
4143
----------
4244
lfp_electrodes_query: element_array_ephys.ephys.LFP.Electrode
4345
chunk_length: int, optional
44-
Chunks are blocks of disk space where data are stored contiguously and compressed
46+
Chunks are blocks of disk space where data are stored contiguously
47+
and compressed
4548
"""
4649
self.lfp_electrodes_query = lfp_electrodes_query
4750
self.electrodes = self.lfp_electrodes_query.fetch("electrode")
4851

4952
first_record = (
5053
self.lfp_electrodes_query & dict(electrode=self.electrodes[0])
51-
).fetch1(as_dict=True)
54+
).fetch1()
5255

5356
self.n_channels = len(self.electrodes)
5457
self.n_tt = len(first_record["lfp"])
@@ -166,7 +169,8 @@ def create_units_table(
166169
nwbfile: pynwb.NWBFile,
167170
paramset_record,
168171
name="units",
169-
desc="data on spiking units"):
172+
desc="data on spiking units"
173+
):
170174
"""
171175
172176
ephys.CuratedClustering.Unit::unit -> units.id
@@ -215,7 +219,8 @@ def create_units_table(
215219
ephys.ProbeInsertion
216220
* ephys.CuratedClustering.Unit
217221
* probe.ProbeType.Electrode
218-
& unit
222+
& dict((k, unit[k]) for k in unit.keys() # excess keys caused errs
223+
if k not in ['spike_times', 'spike_sites', 'spike_depths'])
219224
).fetch1("probe", "shank")
220225

221226
waveform_mean = (
@@ -302,8 +307,8 @@ def add_ephys_units_to_nwb(
302307
def get_electrodes_mapping(electrodes):
303308
"""
304309
Create a mapping from the probe and electrode id to the row number of the electrodes
305-
table. This is used in the construction of the DynamicTableRegion that indicates what rows of the electrodes
306-
table correspond to the data in an ElectricalSeries.
310+
table. This is used in the construction of the DynamicTableRegion that indicates
311+
what rows of the electrodes table correspond to the data in an ElectricalSeries.
307312
308313
Parameters
309314
----------
@@ -356,18 +361,17 @@ def add_ephys_recording_to_nwb(
356361
end_frame: int = None,
357362
):
358363
"""
359-
Read voltage data directly from source files and iteratively transfer them to the NWB file. Automatically
360-
applies lossless compression to the data, so the final file might be smaller than the original, without
361-
data loss. Currently supports Neuropixels data acquired with SpikeGLX or Open Ephys, and relies on SpikeInterface to read the data.
364+
Read voltage data directly from source files and iteratively transfer them to the
365+
NWB file. Automatically applies lossless compression to the data, so the final file
366+
might be smaller than the original, without data loss. Currently supports
367+
Neuropixels data acquired with SpikeGLX or Open Ephys, and relies on SpikeInterface
368+
to read the data.
362369
363370
source data -> acquisition["ElectricalSeries"]
364371
365372
Parameters
366373
----------
367-
session_key: dict
368-
ephys_root_data_dir: str
369-
nwbfile: NWBFile
370-
end_frame: int, optional
374+
session_key: dict ephys_root_data_dir: str nwbfile: NWBFile end_frame: int, optional
371375
Used for small test conversions
372376
"""
373377

@@ -429,8 +433,12 @@ def add_ephys_lfp_from_dj_to_nwb(session_key: dict, nwbfile: pynwb.NWBFile):
429433
"""
430434
Read LFP data from the data in element-aray-ephys
431435
432-
ephys.LFP.Electrode::lfp -> processing["ecephys"].lfp.electrical_series["ElectricalSeries{insertion_number}"].data
433-
ephys.LFP::lfp_time_stamps -> processing["ecephys"].lfp.electrical_series["ElectricalSeries{insertion_number}"].timestamps
436+
ephys.LFP.Electrode::lfp ->
437+
processing["ecephys"].lfp.electrical_series["ElectricalSeries{insertion_number}"
438+
].data
439+
ephys.LFP::lfp_time_stamps ->
440+
processing["ecephys"].lfp.electrical_series["ElectricalSeries{insertion_number}"
441+
].timestamps
434442
435443
Parameters
436444
----------
@@ -475,7 +483,7 @@ def add_ephys_lfp_from_dj_to_nwb(session_key: dict, nwbfile: pynwb.NWBFile):
475483
def add_ephys_lfp_from_source_to_nwb(
476484
session_key: dict, ephys_root_data_dir, nwbfile: pynwb.NWBFile, end_frame=None):
477485
"""
478-
Read the LFP data directly from the source file. Currently, only works for SpikeGLX data.
486+
Read the LFP data from the source file. Currently, only works for SpikeGLX data.
479487
480488
ephys.EphysRecording::recording_datetime -> acquisition
481489
@@ -514,7 +522,8 @@ def add_ephys_lfp_from_source_to_nwb(
514522
extractor = extractors.read_spikeglx(os.path.split(file_path)[0], "imec.lf")
515523
else:
516524
raise ValueError(
517-
f"unsupported acq_software type: {ephys_recording_record['acq_software']}"
525+
"unsupported acq_software type:" +
526+
f"{ephys_recording_record['acq_software']}"
518527
)
519528

520529
if end_frame is not None:
@@ -564,7 +573,7 @@ def ecephys_session_to_nwb(
564573
----------
565574
session_key: dict
566575
raw: bool
567-
Whether to include the raw data from source. SpikeGLX and OpenEphys are supported
576+
Whether to include the raw data from source. SpikeGLX & OpenEphys are supported
568577
spikes: bool
569578
Whether to include CuratedClustering
570579
lfp:
@@ -573,13 +582,14 @@ def ecephys_session_to_nwb(
573582
False - do not convert LFP
574583
end_frame: int, optional
575584
Used to create small test conversions where large datasets are truncated.
576-
lab_key, project_key, and protocol_key: dictionaries used to look up optional additional metadata
585+
lab_key, project_key, and protocol_key: dictionaries to look up optional metadata
577586
nwbfile_kwargs: dict, optional
578-
- If element-session is not being used, this argument is required and must be a dictionary containing
579-
'session_description' (str), 'identifier' (str), and 'session_start_time' (datetime),
580-
the minimal data for instantiating an NWBFile object.
581-
582-
- If element-session is being used, this argument can optionally be used to add over overwrite NWBFile fields.
587+
- If element-session is not being used, this argument is required and must be a
588+
dictionary containing 'session_description' (str), 'identifier' (str), and
589+
'session_start_time' (datetime), the required minimal data for instantiating
590+
an NWBFile object.
591+
- If element-session is being used, this argument can optionally be used to
592+
overwrite NWBFile fields.
583593
"""
584594

585595
session_to_nwb = getattr(ephys._linking_module, 'session_to_nwb', False)
@@ -608,7 +618,8 @@ def ecephys_session_to_nwb(
608618
add_ephys_lfp_from_dj_to_nwb(session_key, nwbfile)
609619

610620
if lfp == "source":
611-
add_ephys_lfp_from_source_to_nwb(session_key, ephys_root_data_dir=ephys_root_data_dir,
621+
add_ephys_lfp_from_source_to_nwb(session_key,
622+
ephys_root_data_dir=ephys_root_data_dir,
612623
nwbfile=nwbfile, end_frame=end_frame)
613624

614625
return nwbfile

0 commit comments

Comments
 (0)