npc-sync 0.2.7__tar.gz → 0.2.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: npc-sync
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: Repackaging of AllenSDK.SyncDataset with extra functionality, compatible with data in the cloud.
5
5
  Author-email: Ben Hardcastle <ben.hardcastle@alleninstitue.org>
6
6
  License: MIT
@@ -16,7 +16,7 @@ dependencies = [
16
16
  "scipy>=1.13.1",
17
17
  "npc-stim>=0.1.23",
18
18
  ]
19
- version = "0.2.7"
19
+ version = "0.2.8"
20
20
  classifiers = [
21
21
  "Development Status :: 3 - Alpha",
22
22
  "Programming Language :: Python :: 3",
@@ -68,6 +68,11 @@ REPLAY_SLOT_SAMPLES = 10_000
68
68
  acquisition buffers. Buffer sizes seen so far (50,000 and 10,000 samples) are multiples
69
69
  of this. Buffer size is not recorded in the sync file metadata."""
70
70
 
71
+ REPLAY_MAX_BUFFER_SAMPLES = 50_000
72
+ """Largest acquisition buffer (0.5 s at 100 kHz) considered when looking for replayed
73
+ buffers. Identical slots separated by more than this are coincidental matches (e.g. quiet
74
+ or periodic stretches of real data) and are ignored."""
75
+
71
76
  SUSPICIOUS_INTERVAL_THRESHOLD = 0.3 / FRAME_RATE
72
77
  DEFINITE_SHORT_INTERVAL_THRESHOLD = 0.05 / FRAME_RATE
73
78
  # at 60 fps we should never have diode-flip intervals this small: consider them anomalous
@@ -175,6 +180,7 @@ def find_replayed_buffers(
175
180
  times: npt.ArrayLike,
176
181
  bits: npt.ArrayLike,
177
182
  slot_samples: int = REPLAY_SLOT_SAMPLES,
183
+ max_buffer_samples: int = REPLAY_MAX_BUFFER_SAMPLES,
178
184
  ) -> tuple[tuple[tuple[int, int], ...], int | None]:
179
185
  """Find acquisition buffers in a sync event list that are replayed copies of a later
180
186
  buffer.
@@ -197,6 +203,8 @@ def find_replayed_buffers(
197
203
  Bit state (all lines) of each event.
198
204
  slot_samples : int
199
205
  Fingerprint slot width in samples. Must divide the buffer size.
206
+ max_buffer_samples : int
207
+ Identical slots further apart than this are not treated as replays.
200
208
 
201
209
  Returns
202
210
  -------
@@ -238,6 +246,10 @@ def find_replayed_buffers(
238
246
  return (), None
239
247
  earlier = slots[:-1][same]
240
248
  lags = slots[1:][same] - earlier
249
+ plausible = lags <= max_buffer_samples // slot_samples
250
+ earlier, lags = earlier[plausible], lags[plausible]
251
+ if lags.size == 0:
252
+ return (), None
241
253
  values, counts = np.unique(lags, return_counts=True)
242
254
  lag = int(values[np.argmax(counts)])
243
255
  if len(values) > 1:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: npc-sync
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: Repackaging of AllenSDK.SyncDataset with extra functionality, compatible with data in the cloud.
5
5
  Author-email: Ben Hardcastle <ben.hardcastle@alleninstitue.org>
6
6
  License: MIT
@@ -94,3 +94,13 @@ def test_known_sessions(session: str) -> None:
94
94
  if not paths:
95
95
  pytest.skip(f"local sync file not available for {session}")
96
96
  assert npc_sync.SyncDataset(paths[0]).invalid_intervals == KNOWN[session]
97
+
98
+
99
+ def test_ignores_identical_slots_beyond_max_buffer_size() -> None:
100
+ rng = np.random.default_rng(1)
101
+ rel = np.sort(rng.choice(10_000, 50, replace=False))
102
+ state = rng.integers(0, 2**32, 50)
103
+ # same slot content 31 slots (310,000 samples) apart: not a plausible buffer
104
+ times = np.concatenate([rel, rel + 310_000])
105
+ bits = np.concatenate([state, state])
106
+ assert npc_sync.sync.find_replayed_buffers(times, bits) == ((), None)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes