Saving a multi-segment recording fails when only some segments have a t_start
维护者通常 1 天内回复
评估
调研方向
从 issue 中提到的三个构造函数开始:src/spikeinterface/core/numpyextractors.py 中的 NumpyRecording 和 SharedMemoryRecording,以及 src/spikeinterface/core/binaryrecordingextractor.py 中的 BinaryRecordingExtractor。阅读它们各自如何处理 get_segment_t_starts,然后运行复现步骤以及指定的 recording 和 binary extractor 测试。完成标准是二进制保存和内存保存都能保留混合的开始时间和 traces,且不会遗留未释放的共享内存。
由索引模型根据 Issue 内容生成。
描述
get_segment_t_starts returns a mixed list such as [None, 100.0] when only some segments have a start time. Three constructors then call float() on every entry. This happens with append_recordings([rec_without_t_start, rec_with_t_start]), and more generally when shift_times has been applied to only some segments.
Reproduction
main at 9ef464e66, Linux (WSL Ubuntu 24.04), Python 3.12.3, numpy 2.5.4, zarr 3.4.2:
import spikeinterface.core as sc
a = sc.generate_recording(num_channels=2, sampling_frequency=1000.0, durations=[3.0], seed=0)
b = sc.generate_recording(num_channels=2, sampling_frequency=1000.0, durations=[2.0], seed=1)
b.shift_times(100.0)
rec = sc.append_recordings([a, b])
print(rec.get_segment_t_starts(), [rec.get_start_time(i) for i in range(2)])
for kwargs in [
dict(format="binary", folder="rec_binary"),
dict(format="memory", shared_memory=False),
dict(format="memory", shared_memory=True),
dict(format="zarr", folder="rec.zarr"),
]:
try:
saved = rec.save(**kwargs)
print(kwargs["format"], "OK", [saved.get_start_time(i) for i in range(2)])
except TypeError as ex:
print(kwargs["format"], f"TypeError: {ex}")
[None, 100.0] [0.0, 100.0]
binary TypeError: float() argument must be a string or a real number, not 'NoneType'
memory TypeError: float() argument must be a string or a real number, not 'NoneType'
memory TypeError: float() argument must be a string or a real number, not 'NoneType'
zarr OK [0.0, array(100.)]
Three details make this worse:
- Binary: the exception comes after all traces are written. In the example,
rec_binarycontainstraces_cached_seg0.rawandtraces_cached_seg1.raw, but neitherbinary.jsonnorsi_folder.json. For a long recording, this means that hours of writing end in a folder that cannot be loaded. - Shared memory: the exception comes before
self.main_shm_owneris set, so__del__raisesAttributeError: 'SharedMemoryRecording' object has no attribute 'main_shm_owner', and the segments are not unlinked. The script ends withresource_tracker: There appear to be 4 leaked shared_memory objects to clean up at shutdown. - Zarr: saving works, but
get_start_time(1)returns a 0-darray(100.)instead of a float.
Cause
get_segment_t_starts only returns None when all segments have no start time. The conversion is in NumpyRecording, SharedMemoryRecording and BinaryRecordingExtractor. In SharedMemoryRecording, main_shm_owner is set after this line, and __del__ reads it.
Possible fix
In the three constructors, keep None:
t_starts = [None if t_start is None else float(t_start) for t_start in t_starts]
With this, the binary and both memory saves work, with start times [0.0, 100.0] and identical traces, and the script no longer reports leaked segments. test_basesorting.py, test_baserecording.py, test_binaryfolder.py, test_binaryrecordingextractor.py and test_numpy_extractors.py still pass (33 tests).
Two separate points would remain: setting main_shm_owner before anything that can fail, so that __del__ is safe after another error, and the 0-d array from zarr. I have not changed them.
I found no report of this case. Nearby: #2515 and #3120 (t_starts lost by save_to_memory) and #3940 (shift_times when t_start is None). I can open a PR with this change and a round-trip test.
- 主要语言
- Python
- 星标
- 870
- 派生
- 284
- 平均合并
- 2 天 3 小时
- 30 天内合并 PR
- 40
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
SpikeInterface/spikeinterface 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 76/100
SpikeInterface/spikeinterface#4924 ·
维护者通常 1 天内回复
-
难度 1/5 1 小时以内 新手友好度 85/100
SpikeInterface/spikeinterface#4842 · 3 条评论 ·
维护者通常 1 天内回复
-
enhancement
难度 2/5 1-3 小时 新手友好度 72/100
SpikeInterface/spikeinterface#4510 · 2 条评论 ·
维护者通常 1 天内回复
-
MountainSort5: expose `pca_seed` / `random_seed` sorter param (pair with MS5 configurable PCA seed)未关闭
难度 4/5 3-5 天 新手友好度 43/100
SpikeInterface/spikeinterface#4919 ·
维护者通常 1 天内回复
-
BaseSorting.select_periods() drops properties, annotations and the registered recording可能已有人在做 @AxelNoun 于 1 天前认领。 未关闭bug core
难度 2/5 1-3 小时 新手友好度 20/100
SpikeInterface/spikeinterface#4915 · 3 条评论 ·
维护者通常 1 天内回复
查看 SpikeInterface/spikeinterface 的全部 Issue
相似的 Issue
-
docs size:S
难度 1/5 1 小时以内 新手友好度 88/100
维护者通常 1 天内回复
-
documentation
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 74/100
strawberry-graphql/strawberry#4794 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
dataforgoodfr/cetolog#21 ·
-
难度 2/5 1-3 小时 新手友好度 76/100
btclib-org/btclib#2932 ·
维护者通常 1 天内回复