figpack 0.2.26__py3-none-any.whl → 0.2.28__py3-none-any.whl
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.
Potentially problematic release.
This version of figpack might be problematic. Click here for more details.
- figpack/__init__.py +1 -1
- figpack/figpack-figure-dist/assets/{index-BIw8xT5I.js → index-DnHZdWys.js} +15 -15
- figpack/figpack-figure-dist/index.html +1 -1
- figpack/views/TimeseriesGraph.py +61 -0
- {figpack-0.2.26.dist-info → figpack-0.2.28.dist-info}/METADATA +1 -1
- {figpack-0.2.26.dist-info → figpack-0.2.28.dist-info}/RECORD +10 -10
- {figpack-0.2.26.dist-info → figpack-0.2.28.dist-info}/WHEEL +0 -0
- {figpack-0.2.26.dist-info → figpack-0.2.28.dist-info}/entry_points.txt +0 -0
- {figpack-0.2.26.dist-info → figpack-0.2.28.dist-info}/licenses/LICENSE +0 -0
- {figpack-0.2.26.dist-info → figpack-0.2.28.dist-info}/top_level.txt +0 -0
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// Allow script injection from trusted domains (see src/main.tsx)
|
|
10
10
|
window.script_injection_allowed_domains = ['https://manage.figpack.org', 'https://figpack.org'];
|
|
11
11
|
</script>
|
|
12
|
-
<script type="module" crossorigin src="./assets/index-
|
|
12
|
+
<script type="module" crossorigin src="./assets/index-DnHZdWys.js"></script>
|
|
13
13
|
<link rel="stylesheet" crossorigin href="./assets/index-V5m_wCvw.css">
|
|
14
14
|
</head>
|
|
15
15
|
<body>
|
figpack/views/TimeseriesGraph.py
CHANGED
|
@@ -135,6 +135,9 @@ class TimeseriesGraph(FigpackView):
|
|
|
135
135
|
channel_names: Optional[List[str]] = None,
|
|
136
136
|
colors: Optional[List[str]] = None,
|
|
137
137
|
width: float = 1.0,
|
|
138
|
+
channel_spacing: Optional[float] = None,
|
|
139
|
+
auto_channel_spacing: Optional[float] = None,
|
|
140
|
+
timestamps_for_inserting_nans: Optional[np.ndarray] = None,
|
|
138
141
|
) -> None:
|
|
139
142
|
"""
|
|
140
143
|
Add a uniform timeseries to the graph with optional multi-channel support
|
|
@@ -147,6 +150,9 @@ class TimeseriesGraph(FigpackView):
|
|
|
147
150
|
channel_names: Optional list of channel names
|
|
148
151
|
colors: Optional list of colors for each channel
|
|
149
152
|
width: Line width
|
|
153
|
+
channel_spacing: Vertical spacing between channels
|
|
154
|
+
auto_channel_spacing: sets channel spacing to this multiple of the estimated RMS noise level
|
|
155
|
+
timestamps_for_inserting_nans: Optional array of timestamps used to determine where to insert NaNs in the data
|
|
150
156
|
"""
|
|
151
157
|
self._series.append(
|
|
152
158
|
TGUniformSeries(
|
|
@@ -157,6 +163,9 @@ class TimeseriesGraph(FigpackView):
|
|
|
157
163
|
channel_names=channel_names,
|
|
158
164
|
colors=colors,
|
|
159
165
|
width=width,
|
|
166
|
+
channel_spacing=channel_spacing,
|
|
167
|
+
auto_channel_spacing=auto_channel_spacing,
|
|
168
|
+
timestamps_for_inserting_nans=timestamps_for_inserting_nans,
|
|
160
169
|
)
|
|
161
170
|
)
|
|
162
171
|
|
|
@@ -312,6 +321,9 @@ class TGUniformSeries:
|
|
|
312
321
|
channel_names: Optional[List[str]] = None,
|
|
313
322
|
colors: Optional[List[str]] = None,
|
|
314
323
|
width: float = 1.0,
|
|
324
|
+
channel_spacing: Optional[float] = None,
|
|
325
|
+
auto_channel_spacing: Optional[float] = None,
|
|
326
|
+
timestamps_for_inserting_nans: Optional[np.ndarray] = None,
|
|
315
327
|
):
|
|
316
328
|
assert sampling_frequency_hz > 0, "Sampling frequency must be positive"
|
|
317
329
|
|
|
@@ -332,6 +344,30 @@ class TGUniformSeries:
|
|
|
332
344
|
self.sampling_frequency_hz = sampling_frequency_hz
|
|
333
345
|
self.data = data.astype(np.float32) # Ensure float32 for efficiency
|
|
334
346
|
|
|
347
|
+
if timestamps_for_inserting_nans is not None:
|
|
348
|
+
self.data = insert_nans_based_on_timestamps(
|
|
349
|
+
self.data,
|
|
350
|
+
start_time_sec=start_time_sec,
|
|
351
|
+
sampling_frequency_hz=sampling_frequency_hz,
|
|
352
|
+
timestamps=timestamps_for_inserting_nans,
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
if auto_channel_spacing is not None:
|
|
356
|
+
if channel_spacing is not None:
|
|
357
|
+
raise ValueError(
|
|
358
|
+
"Specify either channel_spacing or auto_channel_spacing, not both."
|
|
359
|
+
)
|
|
360
|
+
# Estimate RMS noise level across all channels using median absolute deviation
|
|
361
|
+
# Use nanmedian to handle NaN values properly
|
|
362
|
+
mad = np.nanmedian(
|
|
363
|
+
np.abs(self.data - np.nanmedian(self.data, axis=0)), axis=0
|
|
364
|
+
)
|
|
365
|
+
rms_estimate = mad / 0.6745 # Convert MAD to RMS estimate
|
|
366
|
+
channel_spacing = auto_channel_spacing * np.nanmedian(rms_estimate)
|
|
367
|
+
if channel_spacing <= 0 or np.isnan(channel_spacing):
|
|
368
|
+
channel_spacing = 1.0 # Fallback to default spacing if estimate fails
|
|
369
|
+
self.channel_spacing = channel_spacing
|
|
370
|
+
|
|
335
371
|
# Set channel names
|
|
336
372
|
if channel_names is None:
|
|
337
373
|
if n_channels == 1:
|
|
@@ -512,6 +548,9 @@ class TGUniformSeries:
|
|
|
512
548
|
group.attrs["n_timepoints"] = n_timepoints
|
|
513
549
|
group.attrs["n_channels"] = n_channels
|
|
514
550
|
|
|
551
|
+
if self.channel_spacing is not None:
|
|
552
|
+
group.attrs["channel_spacing"] = self.channel_spacing
|
|
553
|
+
|
|
515
554
|
# Store original data with optimal chunking
|
|
516
555
|
original_chunks = self._calculate_optimal_chunk_size(self.data.shape)
|
|
517
556
|
group.create_dataset(
|
|
@@ -535,3 +574,25 @@ class TGUniformSeries:
|
|
|
535
574
|
data=downsampled_array,
|
|
536
575
|
chunks=ds_chunks,
|
|
537
576
|
)
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
def insert_nans_based_on_timestamps(
|
|
580
|
+
x: np.ndarray,
|
|
581
|
+
*,
|
|
582
|
+
start_time_sec: float,
|
|
583
|
+
sampling_frequency_hz: float,
|
|
584
|
+
timestamps: np.ndarray,
|
|
585
|
+
):
|
|
586
|
+
end_timestamps = timestamps[-1]
|
|
587
|
+
ret_length = int((end_timestamps - start_time_sec) * sampling_frequency_hz) + 1
|
|
588
|
+
|
|
589
|
+
# Handle both 1D and 2D (multi-channel) data
|
|
590
|
+
if x.ndim == 1:
|
|
591
|
+
ret = np.nan * np.ones((ret_length,), dtype=x.dtype)
|
|
592
|
+
else: # x.ndim == 2
|
|
593
|
+
n_channels = x.shape[1]
|
|
594
|
+
ret = np.nan * np.ones((ret_length, n_channels), dtype=x.dtype)
|
|
595
|
+
|
|
596
|
+
indices = ((timestamps - start_time_sec) * sampling_frequency_hz).astype(int)
|
|
597
|
+
ret[indices] = x
|
|
598
|
+
return ret
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
figpack/__init__.py,sha256=
|
|
1
|
+
figpack/__init__.py,sha256=ZIM-xRn0YXJHMil7YxRrnjEResxKD-UXM9PQN8sBLOg,358
|
|
2
2
|
figpack/cli.py,sha256=s1mGQuFSntxiIvU6OWwHVlM9Cj-l1zMQ3OzFFe1-5ZE,11089
|
|
3
3
|
figpack/extensions.py,sha256=mILB4_F1RHkca4I7t88zh74IX8VCmfT7XFZZT4XYdNw,13009
|
|
4
4
|
figpack/core/__init__.py,sha256=7zU6O1piTk07aeCfbU81QqTgSHIO2n5MZ4LFNmsrtfs,192
|
|
@@ -14,8 +14,8 @@ figpack/core/extension_view.py,sha256=FSBXdhFEWicLi0jhkuRdS-a8CNsULrEqqIKtYfV3tm
|
|
|
14
14
|
figpack/core/figpack_extension.py,sha256=KSJKlnLYueFnGa8QFMpbIF3CDMwnIZJOqsI0smz6cUc,2252
|
|
15
15
|
figpack/core/figpack_view.py,sha256=rD94SehOcb_OVlZJuVK9UdH-dOJ-Mjlvg5cX1JEoH0w,6853
|
|
16
16
|
figpack/core/zarr.py,sha256=LTWOIX6vuH25STYTQS9_apfnfYXmATAEQkil3z9eYKE,1634
|
|
17
|
-
figpack/figpack-figure-dist/index.html,sha256=
|
|
18
|
-
figpack/figpack-figure-dist/assets/index-
|
|
17
|
+
figpack/figpack-figure-dist/index.html,sha256=RA68WkQC-75AbzX32U3SGbbipP9NpkAMSXJWrfVCPkI,688
|
|
18
|
+
figpack/figpack-figure-dist/assets/index-DnHZdWys.js,sha256=YxHgJeAv3feDI2INjrt9_7a86niyJ8eL7gqaRxU-Zs4,1108653
|
|
19
19
|
figpack/figpack-figure-dist/assets/index-V5m_wCvw.css,sha256=WRtQLW6SNlTlLtepSOt89t1z41SD7XzYUyRldqowjMM,7286
|
|
20
20
|
figpack/figpack-figure-dist/assets/neurosift-logo-CLsuwLMO.png,sha256=g5m-TwrGh5f6-9rXtWV-znH4B0nHgc__0GWclRDLUHs,9307
|
|
21
21
|
figpack/views/Box.py,sha256=oN_OJH2pK_hH26k0eFCFjlfuJssVqKvw20GxYK1HX7g,2419
|
|
@@ -33,15 +33,15 @@ figpack/views/Spectrogram.py,sha256=jcm26ucHedKDnBA5xnAUu9tW-g-ZutT-kw1EIhYm66E,
|
|
|
33
33
|
figpack/views/Splitter.py,sha256=BR2L-8aqicTubS1rSzsQ3XnhoJcX5GcfEnVWtEWEs0w,2016
|
|
34
34
|
figpack/views/TabLayout.py,sha256=AqdHPLcP2-caWjxbkC8r8m60z8n_eyZrIBGOOPSVNCs,1908
|
|
35
35
|
figpack/views/TabLayoutItem.py,sha256=xmHA0JsW_6naJze4_mQuP_Fy0Nm17p2N7w_AsmVRp8k,880
|
|
36
|
-
figpack/views/TimeseriesGraph.py,sha256=
|
|
36
|
+
figpack/views/TimeseriesGraph.py,sha256=hhHhtbgaYMldWeSg76M8WRf9ZkI7-1xc3bLWX3c4Acg,20448
|
|
37
37
|
figpack/views/__init__.py,sha256=V09R6vFRzhY7ANevWomM7muFfUieXZEjGimPiMHpey4,641
|
|
38
38
|
figpack/views/PlotlyExtension/PlotlyExtension.py,sha256=LOFSqbm46UZ7HsHTDxUPnNB33ydYQvEkRVK-TSKkzK4,2149
|
|
39
39
|
figpack/views/PlotlyExtension/__init__.py,sha256=80Wy1mDMWyagjuR99ECxJePIYpRQ6TSyHkB0uZoBZ_0,70
|
|
40
40
|
figpack/views/PlotlyExtension/_plotly_extension.py,sha256=yZjG1NMGlQedeeLdV6TQWpi_NTm5Wfk5eWbXEdZbbFE,1455
|
|
41
41
|
figpack/views/PlotlyExtension/plotly_view.js,sha256=9BjgOPkqGl87SSonnb48nFeQV3UTIi1trpSPxd9qlKo,3055
|
|
42
|
-
figpack-0.2.
|
|
43
|
-
figpack-0.2.
|
|
44
|
-
figpack-0.2.
|
|
45
|
-
figpack-0.2.
|
|
46
|
-
figpack-0.2.
|
|
47
|
-
figpack-0.2.
|
|
42
|
+
figpack-0.2.28.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
43
|
+
figpack-0.2.28.dist-info/METADATA,sha256=SexqCXW831vYDik27uUYBKr2EokWoXCYpgL0mgG3EbM,4618
|
|
44
|
+
figpack-0.2.28.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
45
|
+
figpack-0.2.28.dist-info/entry_points.txt,sha256=l6d3siH2LxXa8qJGbjAqpIZtI5AkMSyDeoRDCzdrUto,45
|
|
46
|
+
figpack-0.2.28.dist-info/top_level.txt,sha256=lMKGaC5xWmAYBx9Ac1iMokm42KFnJFjmkP2ldyvOo-c,8
|
|
47
|
+
figpack-0.2.28.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|