Source code for ipfx.nwb_append

from pathlib import Path
from typing import (
    List, Dict, Optional, Union
)

import shutil

import pynwb
from hdmf.backends.hdf5.h5_utils import H5DataIO
from pynwb import TimeSeries
from pynwb import ProcessingModule
import numpy as np


PathLike = Union[
    str,
    Path
]


[docs]def append_spike_times(input_nwb_path: PathLike, sweep_spike_times: Dict[int, List[float]], output_nwb_path: Optional[PathLike] = None): """ Appends spiketimes to an nwb2 file Paramters --------- input_nwb_path: location of input nwb file without spiketimes spike_times: Dict of sweep_num: spiketimes output_nwb_path: optional location to write new nwb file with spiketimes, otherwise appends spiketimes to input file """ # Copy to new location if output_nwb_path and output_nwb_path != input_nwb_path: shutil.copy(input_nwb_path, output_nwb_path) nwb_path = output_nwb_path else: nwb_path = input_nwb_path nwb_io = pynwb.NWBHDF5IO(nwb_path, mode='a', load_namespaces=True) nwbfile = nwb_io.read() spikes_module = "spikes" # Add spikes only if not previously added if spikes_module not in nwbfile.processing.keys(): spike_module = ProcessingModule(name=spikes_module, description='detected spikes') for sweep_num, spike_times in sweep_spike_times.items(): wrapped_spike_times = H5DataIO(data=np.asarray(spike_times), compression=True) ts = TimeSeries(timestamps=wrapped_spike_times, unit='seconds', data=wrapped_spike_times, name=f"Sweep_{sweep_num}") spike_module.add_data_interface(ts) nwbfile.add_processing_module(spike_module) # Because the NWB schema versions of NWB data produced by MIES are older # we do not want to cache the newer schema versions that IPFX is currently using # WARNING: Doing this may introduce fragility down the road though if IPFX writes NWB fields # that require the newer schema versions... nwb_io.write(nwbfile, cache_spec=False) else: raise ValueError("Cannot add spikes times to the nwb file: " "spikes times already exist!") nwb_io.close()