You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Loop through new timestamps to find the closest old timestamp
52
+
# Handle timestamps outside of the segment (too young or too old) different from stamnps from within the segment
48
53
fornix, ntsinenumerate(new_timestamps):
49
-
closest= (np.abs(old_timestamps-nts)).argmin()
50
-
# remember the edge cases,
51
-
if (nts>ts_last):
54
+
ifnts>ts_last:
52
55
too_young.append((nix, nts))
53
-
elif(nts<ts_first):
54
-
too_old.append((nix,nts))
56
+
elifnts<ts_first:
57
+
too_old.append((nix,nts))
55
58
else:
56
-
closest= (np.abs(old_timestamps-nts)).argmin()
57
-
source.append(closest)
58
-
target.append(nix)
59
-
# check the edge cases,
60
-
fornix, ntsinreversed(too_old):
61
-
closest= (np.abs(old_timestamps-nts)).argmin()
62
-
if (closestnotinsource):
59
+
closest=np.abs(old_timestamps-nts).argmin()
60
+
ifclosestnotinsource: # Ensure unique mapping
61
+
source.append(closest)
62
+
target.append(nix)
63
+
else:
64
+
raiseRuntimeError(
65
+
f"Non-unique mapping. Closest old timestamp for {new_timestamps[nix]} is {old_timestamps[closest]} but that one was already assigned to {new_timestamps[source.index(closest)]}"
66
+
)
67
+
68
+
# Handle too old timestamps (those before the first old timestamp)
69
+
fornix, ntsintoo_old:
70
+
closest=0# Assign to the first timestamp
71
+
ifclosestnotinsource: # Ensure unique mapping
63
72
source.append(closest)
64
73
target.append(nix)
65
-
break
74
+
break# only one, because we only need the edge
75
+
76
+
# Handle too young timestamps (those after the last old timestamp)
66
77
fornix, ntsintoo_young:
67
-
closest=(np.abs(old_timestamps-nts)).argmin()
68
-
if(closestnotinsource):
78
+
closest=len(old_timestamps)-1# Assign to the last timestamp
79
+
ifclosestnotinsource: # Ensure unique mapping
69
80
source.append(closest)
70
81
target.append(nix)
71
-
break
72
-
73
-
iflen(set(source)) !=len(old_timestamps):
74
-
missed=len(old_timestamps)-len(set(source))
75
-
raiseRuntimeError(f"Too few new timestamps. {missed} of {len(old_timestamps)} old samples could not be assigned.")
f"Old timestamp {ts} was not assigned to any new timestamp. Closest new timestamp is {new_timestamps[np.abs(new_timestamps-ts).argmin()]}"
91
+
)
92
+
raiseRuntimeError(
93
+
f"Too few new timestamps. {missed} old timestamps ({old_timestamps[unassigned_old]}) found no corresponding new timestamp because it was already taken by another old timestamp."
94
+
)
95
+
96
+
# Populate new timeseries with aligned values from old_timeseries
streams: a list of defaultdicts (i.e. streams) as returned by
115
+
streams: a list of defaultdicts (i.e. streams) as returned by
103
116
load_xdf
104
-
align_foo: a dictionary mapping streamIDs (i.e. int) to interpolation
105
-
callables. These callables must have the signature
117
+
align_foo: a dictionary mapping streamIDs (i.e. int) to interpolation
118
+
callables. These callables must have the signature
106
119
`interpolate(old_timestamps, old_timeseries, new_timestamps)` and return a np.ndarray. See `_shift_align` and `_interpolate` for examples.
107
-
aligned_timestamps (optional): a list of floats with the new
120
+
aligned_timestamps (optional): a list of floats with the new
108
121
timestamps to be used for alignment/interpolation. This list of timestamps can be irregular and have gaps.
109
-
sampling_rate (optional): a float defining the sampling rate which
122
+
sampling_rate (optional): a float defining the sampling rate which
110
123
will be used to calculate aligned_timestamps.
111
-
124
+
112
125
Return:
113
126
(aligned_timeseries, aligned_timestamps): tuple
114
127
115
128
116
-
THe user can define either aligned_timestamps or sampling_rate or neither. If neither is defined, the algorithm will take the sampling_rate of the fastest stream and create aligned_timestamps from the oldest sample of all streams to the youngest.
117
-
129
+
THe user can define either aligned_timestamps or sampling_rate or neither. If neither is defined, the algorithm will take the sampling_rate of the fastest stream and create aligned_timestamps from the oldest sample of all streams to the youngest.
# using np.linspace only differs in step if n_samples is different (as n_samples must be an integer number (see implementation below).
142
-
# therefore we stick with np.arange (in spite of possible floating point error accumulation, but to make sure that ts_last is included, we add a half-step. This therefore comes at the cost of a overshoot, but i consider this acceptable considering this stamp would only be from one stream, and not part of all other and therefore is kind of arbitray anyways.
# https://stackoverflow.com/questions/1704823/create-numpy-matrix-filled-with-nans The timings show a preference for ndarray.fill(..) as the faster alternative.
0 commit comments