Pynapple timestamps are relative to an undefined origin. To synchronize data streams across hardware, this feature adds a time_origin attribute that anchors pynapple objects to UTC. No existing code breaks -- when time_origin is None (default), all behavior is identical.
IRIG-specific decoding and synchronization logic lives in a separate package: neurokairos-pynapple.
| Function / Method | Purpose |
|---|---|
.set_time_origin(origin) |
Return a new object with time_origin set (timestamps unchanged) |
| Function / Method | Purpose |
|---|---|
.sync_to(other) |
Return a new object with timestamps shifted to match other's time origin |
| Function / Method | Purpose |
|---|---|
nap.concatenate(*objects) |
Concatenate time series along the time axis with time_origin checking and propagation |
| Function / Method | Purpose |
|---|---|
.origin_datetime() |
UTC datetime of recording start (time_origin as datetime) |
.time_origin |
Float (unix timestamp of t=0) or None |
- Internal storage: drift-corrected relative timestamps (not unix time). Avoids breaking
restrict(),get(), and manualIntervalSetcreation. time_origin: optional attribute on all objects.None= not synced (default).- Compatibility enforcement: operations between two objects error if one is synced and the other isn't, or if their
time_originvalues differ. BothNone= no checking (backward compatible). - Time-referencing (anchoring an object to an external time reference):
.set_time_origin()stamps an origin on an object without changing timestamps. IRIG-based time-referencing (decode + drift correct + set origin) is provided by the separateneurokairos-pynapplepackage. - Synchronization (shifting one time-referenced object to match another):
.sync_to(other)shifts timestamps by the offset between two origins so both objects share a common timebase. Both objects must already be time-referenced (have atime_origin) before synchronization can occur. - Propagation:
time_originpropagates throughrestrict(),count(),copy(),save()/load(), etc.
Files: base_class.py, interval_set.py, ts_group.py
- Add
time_origin=Noneparameter to__init__of_Base,IntervalSet,TsGroup - Store before
_initialized = True - Add
.origin_datetime()method - Add
.set_time_origin(origin)method -- returns a new object withtime_originset, timestamps unchanged - Add
.sync_to(other)method -- returns a new object with timestamps shifted to matchother's time origin (requires both objects to havetime_originset) time_supportIntervalSets inherittime_originfrom their parent
File: base_class.py (helper), inserted into all two-object operations
_check_time_origin_compatibility(obj_a, obj_b)-- raisesTypeErrorif mixing synced/unsynced,ValueErrorif origins differ- Time series methods:
restrict(),value_from(),count(ep=...),in_interval() - IntervalSet set operations:
intersect(),union(),set_diff(),in_interval() - TsGroup methods:
restrict(),value_from(),count(ep=...),merge()/merge_group() - Concatenation:
nap.concatenate()and thenp.concatenatehook (_concatenate_tsd)
Files: time_series.py, interval_set.py, ts_group.py, utils.py
_define_instance()passesself.time_originto new objects_initialize_tsd_output()propagates from input- IntervalSet set operations propagate
time_origin _concatenate_tsd()checks compatibility across inputs and propagates to output_split_tsd()propagates from input to each split piece
File: pynapple/core/utils.py or new file
- Dedicated
nap.concatenate(*objects)function for concatenating time series along the time axis - Checks
time_origincompatibility across all inputs - Requires strictly increasing, non-overlapping timestamps
- Propagates
time_originto the result - Existing
np.concatenatehook (_concatenate_tsd) also gains the same checks
File: pynapple/io/interface_npz.py
- Save
time_originas NPZ key when notNone; load and pass to constructor if present; old files load withtime_origin=None
- Add sync indicator to
__repr__whentime_originis set
File: pynapple/core/__init__.py
- Export
concatenate
File: tests/test_time_origin.py (new)
- Tests:
time_originpropagation, backward compatibility, compatibility errors,.set_time_origin(),.sync_to(),nap.concatenate()
| File | Action |
|---|---|
pynapple/core/base_class.py |
Modify -- time_origin, .origin_datetime(), .set_time_origin(), .sync_to(), checks |
pynapple/core/time_series.py |
Modify -- propagation |
pynapple/core/interval_set.py |
Modify -- time_origin, propagation |
pynapple/core/ts_group.py |
Modify -- time_origin, propagation, checks |
pynapple/core/utils.py |
Modify -- nap.concatenate(), time_origin in _concatenate_tsd/_split_tsd |
pynapple/core/__init__.py |
Modify -- exports |
pynapple/io/interface_npz.py |
Modify -- save/load |
tests/test_time_origin.py |
New |
pytest tests/-- all existing tests passpytest tests/test_time_origin.py -v-- new tests pass- Lint passes