Skip to content

Commit

Permalink
Merge pull request #85 from LorenFrankLab/num_hwChan_resolution
Browse files Browse the repository at this point in the history
Num hw chan resolution
  • Loading branch information
edeno authored Feb 3, 2024
2 parents a52dfa1 + a82f1d7 commit 057760a
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 5 deletions.
4 changes: 3 additions & 1 deletion src/trodes_to_nwb/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,9 @@ def _create_nwb(

logger.info("CREATING REC DATA ITERATORS")
# make generic rec file data chunk iterator to pass to functions
rec_dci = RecFileDataChunkIterator(rec_filepaths, interpolate_dropped_packets=False)
rec_dci = RecFileDataChunkIterator(
rec_filepaths, interpolate_dropped_packets=False, stream_id="trodes"
)
rec_dci_timestamps = (
rec_dci.timestamps
) # pass these when creating other non-interpolated rec iterators to save time
Expand Down
50 changes: 48 additions & 2 deletions src/trodes_to_nwb/convert_ephys.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,36 @@ def __init__(
rec_file_path: list[str],
nwb_hw_channel_order=[],
conversion: float = 1.0,
stream_index: int = 3, # TODO use the stream name instead of the index
stream_index: int = None, # TODO use the stream name instead of the index
stream_id: str = None,
is_analog: bool = False,
interpolate_dropped_packets: bool = False,
timestamps=None, # Use this if you already have timestamps from intializing another rec iterator on the same files
**kwargs,
):
"""
Parameters
----------
rec_file_path : list[str]
list of paths to rec files
nwb_hw_channel_order : list, optional
order of hw channels in the nwb file, by default []
conversion : float, optional
conversion factor from raw data to volts, by default 1.0
stream_index : int, optional
index of stream to use. If both this and stream_id provided values must match in rec header, by default None
stream_id : str, optional
id name of stream to use. If both this and stream_index provided values must match in rec header, by default None
is_analog : bool, optional
whether this is an analog stream, by default False
interpolate_dropped_packets : bool, optional
whether to interpolate single dropped packets, by default False
timestamps : [type], optional
timestamps to use. Can provide efficiency improvements by skipping recalculating timestamps from rec files, by default None
kwargs : dict
additional arguments to pass to GenericDataChunkIterator
"""
if not rec_file_path:
raise FileNotFoundError("Must provide at least one rec file path")
logger = logging.getLogger("convert")
Expand All @@ -59,7 +83,23 @@ def __init__(

self.block_index = 0
self.seg_index = 0
self.stream_index = stream_index # TODO confirm that the stream index is trodes

# resolve stream index and id based on rec header and provided info
if stream_id is not None: # if stream id is provided
if (
stream_index is None
): # if stream index is not provided, get from the SpikegadgetsRawIO object
stream_index = self.neo_io[0].get_stream_index_from_id(stream_id)
# if both provided, check that they agree
elif not self.neo_io[0].get_stream_id_from_index(stream_index) == stream_id:
raise ValueError(
f"Provided stream index {stream_index} does not match provided stream id {stream_id}"
)
else: # if stream id is not provided
stream_id = self.neo_io[0].get_stream_id_from_index(stream_index)

self.stream_id = stream_id
self.stream_index = stream_index

# check that all files have the same number of channels.
if (
Expand Down Expand Up @@ -87,6 +127,11 @@ def __init__(
else:
self.nwb_hw_channel_order = nwb_hw_channel_order

if (
self.stream_id == "trodes"
and len(self.nwb_hw_channel_order) < self.n_channel
):
self.n_channel = len(self.nwb_hw_channel_order)
"""split excessively large iterators into smaller ones
"""
iterator_size = [neo_io._raw_memmap.shape[0] for neo_io in self.neo_io]
Expand Down Expand Up @@ -298,6 +343,7 @@ def add_raw_ephys(
nwb_hw_channel_order=nwb_hw_chan_order,
conversion=conversion,
interpolate_dropped_packets=True,
stream_id="trodes",
) # can set buffer_gb if needed

# (16384, 32) chunks of dtype int16 (2 bytes) is 1 MB, which is recommended
Expand Down
15 changes: 15 additions & 0 deletions src/trodes_to_nwb/spike_gadgets_raw_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ def _parse_header(self):

self._sampling_rate = float(hconf.attrib["samplingRate"])
num_ephy_channels = int(hconf.attrib["numChannels"])
# check for agreement with number of channels in xml
sconf_channels = np.sum([len(x) for x in sconf])
if sconf_channels < num_ephy_channels:
num_ephy_channels = sconf_channels
if sconf_channels > num_ephy_channels:
raise ValueError(
"SpikeGadgets: the number of channels in the spike configuration is larger than the number of channels in the hardware configuration"
)

try:
num_chan_per_chip = int(sconf.attrib["chanPerChip"])
except KeyError:
Expand Down Expand Up @@ -746,6 +755,12 @@ def _interpolate_raw_memmap(
print("Interpolate memmap: ", self.filename)
self._raw_memmap = InsertedMemmap(self._raw_memmap, self.interpolate_index)

def get_stream_index_from_id(self, stream_id):
return np.where(self.header["signal_streams"]["id"] == stream_id)[0][0]

def get_stream_id_from_index(self, stream_index):
return self.header["signal_streams"]["id"][stream_index]


class InsertedMemmap:
"""
Expand Down
5 changes: 3 additions & 2 deletions src/trodes_to_nwb/tests/test_convert_intervals.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ def test_add_epochs():
rec_to_nwb_file = data_path / "minirec20230622_.nwb" # comparison file
# get all streams for all files
rec_dci = RecFileDataChunkIterator(
file_info[file_info.file_extension == ".rec"].full_path.to_list()
file_info[file_info.file_extension == ".rec"].full_path.to_list(),
stream_id="trodes",
)
add_epochs(nwbfile, file_info, rec_dci.neo_io)
epochs_df = nwbfile.epochs.to_dataframe()
Expand All @@ -49,7 +50,7 @@ def test_add_sample_count():
rec_to_nwb_file = data_path / "minirec20230622_.nwb" # comparison file

# make recfile data chunk iterator
rec_dci = RecFileDataChunkIterator(recfile)
rec_dci = RecFileDataChunkIterator(recfile, stream_id="trodes")

# add sample counts
add_sample_count(nwbfile, rec_dci)
Expand Down

0 comments on commit 057760a

Please sign in to comment.