misleep 0.3.1__tar.gz → 0.3.2__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.
Potentially problematic release.
This version of misleep might be problematic. Click here for more details.
- {misleep-0.3.1 → misleep-0.3.2}/CHANGELOG.md +16 -0
- {misleep-0.3.1/src/misleep.egg-info → misleep-0.3.2}/PKG-INFO +1 -1
- {misleep-0.3.1 → misleep-0.3.2}/docs/config_file.md +4 -4
- {misleep-0.3.1 → misleep-0.3.2}/pyproject.toml +1 -1
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/__init__.py +1 -1
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/config/default_config.ini +2 -2
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/data/midata.py +15 -5
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/about.ui +2 -2
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/about_ui.py +2 -2
- {misleep-0.3.1 → misleep-0.3.2/src/misleep.egg-info}/PKG-INFO +1 -1
- {misleep-0.3.1 → misleep-0.3.2}/tests/test_data.py +53 -0
- {misleep-0.3.1 → misleep-0.3.2}/tests/test_gui.py +1 -1
- {misleep-0.3.1 → misleep-0.3.2}/LICENSE +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/MANIFEST.in +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/README.md +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/docs/api_reference.md +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/docs/data_formats.md +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/docs/developer_guide.md +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/docs/getting_started.md +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/docs/imgs/entire_logo.png +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/docs/imgs/gui/main_light.png +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/docs/imgs/logo.png +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/docs/index.md +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/docs/user_guide.md +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/examples/auto_stage_example.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/examples/basic_usage.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/examples/extend_io_example.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/setup.cfg +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/__main__.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/_compat.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/__init__.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/auto_stage.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/autostage/__init__.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/autostage/benchmark.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/autostage/features.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/autostage/hmm.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/autostage/model.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/autostage/postprocess.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/detection.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/features.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/models/__init__.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/models/benchmark_models.pkl +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/transformer/__init__.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/transformer/checkpoints/CausalTransformer_best.pt +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/transformer/checkpoints/__init__.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/transformer/configs.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/transformer/data.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/transformer/inference.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/transformer/models.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/analysis/transformer/preprocessing.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/config/__init__.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/data/__init__.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/data/annotation.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/__init__.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/app.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/config_dialog.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/dialogs.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/event_filters.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/main_window.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/qt_utils.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/resources/__init__.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/resources/entire_logo.png +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/resources/logo.png +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/resources/misleep.ico +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/resources/misleep.qrc +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/resources/misleep_rc.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/spec_window.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/style.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/SWA_detect_dialog.ui +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/SWA_detect_dialog_ui.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/__init__.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/auto_stage_causalTransformer_dialog.ui +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/auto_stage_causalTransformer_dialog_ui.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/auto_stage_lightGBM_dialog.ui +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/auto_stage_lightGBM_dialog_ui.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/horizontal_line_dialog.ui +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/horizontal_line_dialog_ui.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/label_dialog.ui +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/label_dialog_ui.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/main_window.ui +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/main_window_ui.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/save_data_dialog.ui +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/save_data_dialog_ui.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/spec_window.ui +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/spec_window_ui.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/spindle_detect_dialog.ui +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/spindle_detect_dialog_ui.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/state_spectral_dialog.ui +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/state_spectral_dialog_ui.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/transfer_result_dialog.ui +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/transfer_result_dialog_ui.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/workers.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/io/__init__.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/io/annotation.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/io/array.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/io/base.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/io/edf.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/io/mat.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/logger.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/preprocessing/__init__.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/preprocessing/artifacts.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/preprocessing/filtering.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/preprocessing/segment.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/preprocessing/spectral.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/utils/__init__.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/utils/annotation.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/utils/entropy.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/utils/misc.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/utils/time_utils.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/viz/__init__.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/viz/hypnogram.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/viz/signals.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep/viz/spectral.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep.egg-info/SOURCES.txt +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep.egg-info/dependency_links.txt +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep.egg-info/entry_points.txt +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep.egg-info/requires.txt +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/src/misleep.egg-info/top_level.txt +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/tests/test_analysis.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/tests/test_io.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/tests/test_preprocessing.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/tests/test_segment.py +0 -0
- {misleep-0.3.1 → misleep-0.3.2}/tests/test_viz_config.py +0 -0
|
@@ -5,6 +5,22 @@ All notable changes to MiSleep are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.3.2] — 2026-08-24
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **Filtering broke on fractional sampling frequencies**: `MiData.add()` (used
|
|
13
|
+
by `MiData.filter()`) recomputed the duration with
|
|
14
|
+
`math.floor(len(signal) / sf)` from a signal that had already been
|
|
15
|
+
truncated to `int(duration * sf)` samples. When `sf` is a decimal (e.g.
|
|
16
|
+
`99.9927` Hz), that came out one second short, so filtering either raised a
|
|
17
|
+
spurious "new signal is shorter" error or produced a channel whose length /
|
|
18
|
+
duration did not match the original signal, which then failed the signal /
|
|
19
|
+
label consistency checks in the GUI. The check now compares sample counts
|
|
20
|
+
against `int(duration * sf)` directly, so filtering preserves the sample
|
|
21
|
+
count and duration for any positive `sf` while still rejecting genuinely
|
|
22
|
+
short signals.
|
|
23
|
+
|
|
8
24
|
## [0.3.1] — 2026-08-18
|
|
9
25
|
|
|
10
26
|
### Added
|
|
@@ -23,8 +23,8 @@ wipe your personal settings. Open the user file from the GUI via
|
|
|
23
23
|
|
|
24
24
|
| key | default | meaning |
|
|
25
25
|
|-----|---------|---------|
|
|
26
|
-
| `version` | `v0.3.
|
|
27
|
-
| `updatetime` | `2026/08/
|
|
26
|
+
| `version` | `v0.3.2` | displayed in the About dialog |
|
|
27
|
+
| `updatetime` | `2026/08/24` | displayed in the About dialog |
|
|
28
28
|
| `marker` | `['half_signal', 'first REM', ...]` | marker label list (label picker) |
|
|
29
29
|
| `startend` | `['high_theta', 'REM', ...]` | start-end label list (label picker) |
|
|
30
30
|
| `statemap` | `{"1": "NREM", "2": "REM", "3": "Wake", "4": "INIT", ...}` | state code -> name mapping (JSON) |
|
|
@@ -48,8 +48,8 @@ wipe your personal settings. Open the user file from the GUI via
|
|
|
48
48
|
|
|
49
49
|
```ini
|
|
50
50
|
[gui]
|
|
51
|
-
version = v0.3.
|
|
52
|
-
updatetime = 2026/08/
|
|
51
|
+
version = v0.3.2
|
|
52
|
+
updatetime = 2026/08/24
|
|
53
53
|
marker = ['half_signal', 'first REM', 'WindEEG', 'W-R', 'maker']
|
|
54
54
|
startend = ['high_theta', 'REM', 'Wake', 'Spindle', 'SWA', 'start end label', 'start end label']
|
|
55
55
|
statemap = {"1": "NREM", "2": "REM", "3": "Wake", "4": "INIT", "5": "IS", "6": "MicroArousal"}
|
|
@@ -22,7 +22,7 @@ works without PySide6; import ``misleep.gui`` explicitly when needed.
|
|
|
22
22
|
from importlib import import_module
|
|
23
23
|
|
|
24
24
|
__author__ = "Xueqiang Wang <swang9194@gmail.com>"
|
|
25
|
-
__version__ = "0.3.
|
|
25
|
+
__version__ = "0.3.2"
|
|
26
26
|
|
|
27
27
|
# Importing ``misleep`` used to import scipy, pandas, sklearn and matplotlib
|
|
28
28
|
# immediately. The GUI necessarily imports some of those later, but making
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
# overwritten on the next package update.
|
|
16
16
|
|
|
17
17
|
[gui]
|
|
18
|
-
version = v0.3.
|
|
19
|
-
updatetime = 2026/08/
|
|
18
|
+
version = v0.3.2
|
|
19
|
+
updatetime = 2026/08/24
|
|
20
20
|
marker = ['half_signal', 'first REM', 'WindEEG', 'W-R', 'maker']
|
|
21
21
|
startend = ['high_theta', 'REM', 'Wake', 'Spindle', 'SWA', 'start end label', 'start end label']
|
|
22
22
|
statemap = {"1": "NREM", "2": "REM", "3": "Wake", "4": "INIT"}
|
|
@@ -210,15 +210,25 @@ class MiData:
|
|
|
210
210
|
if not isinstance(sf, (int, float)) or not math.isfinite(sf) or sf <= 0:
|
|
211
211
|
raise TypeError(f"Sample frequency should be a float, got {type(sf)}")
|
|
212
212
|
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
# Every channel shares the same integer duration: the sample count a
|
|
214
|
+
# channel of ``sf`` Hz needs to cover ``self._duration`` seconds is
|
|
215
|
+
# ``int(self._duration * sf)`` (the same truncation used in
|
|
216
|
+
# :meth:`__init__`). Compare sample counts directly instead of
|
|
217
|
+
# re-deriving the duration from an already-truncated length -- with a
|
|
218
|
+
# fractional sampling frequency (e.g. 99.9927 Hz) the naive
|
|
219
|
+
# ``math.floor(len(signal) / sf)`` can come out one second short and
|
|
220
|
+
# wrongly reject signals that are exactly as long as the existing
|
|
221
|
+
# channels (this made ``MiData.filter()`` fail on fractional-sf data).
|
|
222
|
+
expected_samples = int(self._duration * sf)
|
|
223
|
+
if len(signal) < expected_samples:
|
|
215
224
|
raise ValueError(
|
|
216
|
-
f"The new signal is shorter ({
|
|
217
|
-
f"({self._duration}s
|
|
225
|
+
f"The new signal is shorter ({len(signal)} samples) than the "
|
|
226
|
+
f"existing data ({self._duration}s, {expected_samples} samples "
|
|
227
|
+
f"at {sf} Hz)")
|
|
218
228
|
|
|
219
229
|
channel = _unique_name(channel, self.channels)
|
|
220
230
|
|
|
221
|
-
self._signals.append(signal[:
|
|
231
|
+
self._signals.append(signal[:expected_samples])
|
|
222
232
|
self._channels.append(channel)
|
|
223
233
|
self._n_channels = len(self._channels)
|
|
224
234
|
self._sf.append(sf)
|
|
@@ -58,14 +58,14 @@
|
|
|
58
58
|
<item>
|
|
59
59
|
<widget class="QLabel" name="VersionLabel">
|
|
60
60
|
<property name="text">
|
|
61
|
-
<string>Version: 0.3.
|
|
61
|
+
<string>Version: 0.3.2</string>
|
|
62
62
|
</property>
|
|
63
63
|
</widget>
|
|
64
64
|
</item>
|
|
65
65
|
<item>
|
|
66
66
|
<widget class="QLabel" name="UpdateLabel">
|
|
67
67
|
<property name="text">
|
|
68
|
-
<string>Update: 2026/08/
|
|
68
|
+
<string>Update: 2026/08/24</string>
|
|
69
69
|
</property>
|
|
70
70
|
</widget>
|
|
71
71
|
</item>
|
|
@@ -73,8 +73,8 @@ class Ui_AboutDialog(object):
|
|
|
73
73
|
AboutDialog.setWindowTitle(QCoreApplication.translate("AboutDialog", u"About", None))
|
|
74
74
|
self.label_4.setText(QCoreApplication.translate("AboutDialog", u"<html><head/><body><p><img src=\":/logo/entire_logo.png\"/></p></body></html>", None))
|
|
75
75
|
self.groupBox.setTitle(QCoreApplication.translate("AboutDialog", u"MiSleep", None))
|
|
76
|
-
self.VersionLabel.setText(QCoreApplication.translate("AboutDialog", u"Version: 0.3.
|
|
77
|
-
self.UpdateLabel.setText(QCoreApplication.translate("AboutDialog", u"Update: 2026/08/
|
|
76
|
+
self.VersionLabel.setText(QCoreApplication.translate("AboutDialog", u"Version: 0.3.2", None))
|
|
77
|
+
self.UpdateLabel.setText(QCoreApplication.translate("AboutDialog", u"Update: 2026/08/24", None))
|
|
78
78
|
self.CopyrightLabel.setText(QCoreApplication.translate("AboutDialog", u"Copyright \u00a9 2023\u20132026 Xueqiang Wang.", None))
|
|
79
79
|
# retranslateUi
|
|
80
80
|
|
|
@@ -88,6 +88,59 @@ def test_midata_filter(midata):
|
|
|
88
88
|
assert midata.channels[-1].startswith("EEG_bandpass")
|
|
89
89
|
|
|
90
90
|
|
|
91
|
+
@pytest.mark.parametrize("sf", [99.9927, 100.5, 256.256, 305.005])
|
|
92
|
+
def test_midata_filter_fractional_sf_preserves_length(sf):
|
|
93
|
+
"""Filtering must not change the sample count or duration when sf is fractional.
|
|
94
|
+
|
|
95
|
+
Regression: ``MiData.add`` re-derived the duration with
|
|
96
|
+
``math.floor(len(signal) / sf)`` from a signal already truncated to
|
|
97
|
+
``int(duration * sf)`` samples; with a fractional sf that could come out
|
|
98
|
+
one second short and made ``filter()`` raise a spurious error (or produce
|
|
99
|
+
a shorter channel).
|
|
100
|
+
"""
|
|
101
|
+
rng = np.random.default_rng(42)
|
|
102
|
+
n_raw = int(1000 * sf)
|
|
103
|
+
md = MiData(signals=[rng.standard_normal(n_raw),
|
|
104
|
+
rng.standard_normal(n_raw)],
|
|
105
|
+
channels=["EEG", "EMG"], sf=[sf, sf], time="20240101-00:00:00")
|
|
106
|
+
duration, lengths = md.duration, [len(s) for s in md.signals]
|
|
107
|
+
|
|
108
|
+
md.filter(chans=["EEG"], btype="bandpass", low=0.5, high=30)
|
|
109
|
+
|
|
110
|
+
assert md.n_channels == 3
|
|
111
|
+
assert md.duration == duration
|
|
112
|
+
assert len(md.signals) == 3
|
|
113
|
+
assert all(len(sig) == length for sig, length in zip(md.signals, lengths))
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def test_midata_add_fractional_sf():
|
|
117
|
+
"""A channel with ``int(duration * sf)`` samples must be accepted."""
|
|
118
|
+
sf = 99.9927
|
|
119
|
+
md = MiData(signals=[np.zeros(int(1000 * sf)), np.zeros(int(1000 * sf))],
|
|
120
|
+
channels=["EEG", "EMG"], sf=[sf, sf], time="20240101-00:00:00")
|
|
121
|
+
n = md.n_channels
|
|
122
|
+
duration, expected = md.duration, int(md.duration * sf)
|
|
123
|
+
|
|
124
|
+
# Exactly as many samples as the existing channels -> accepted as-is
|
|
125
|
+
md.add(np.zeros(expected), "EEG2", sf)
|
|
126
|
+
assert md.n_channels == n + 1
|
|
127
|
+
assert len(md.signals[-1]) == expected
|
|
128
|
+
assert md.duration == duration # duration unchanged by add()
|
|
129
|
+
|
|
130
|
+
# A genuinely shorter signal is still rejected
|
|
131
|
+
with pytest.raises(ValueError):
|
|
132
|
+
md.add(np.zeros(expected - 10), "TOO_SHORT", sf)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def test_midata_add_fractional_sf_rejects_short_signal():
|
|
136
|
+
"""Fractional-sf channels that are truly too short must still be rejected."""
|
|
137
|
+
sf = 256.256
|
|
138
|
+
md = MiData(signals=[np.zeros(int(1000 * sf)), np.zeros(int(1000 * sf))],
|
|
139
|
+
channels=["EEG", "EMG"], sf=[sf, sf], time="20240101-00:00:00")
|
|
140
|
+
with pytest.raises(ValueError):
|
|
141
|
+
md.add(np.zeros(500 * 256), "TOO_SHORT", 256.0)
|
|
142
|
+
|
|
143
|
+
|
|
91
144
|
def test_midata_differential(midata):
|
|
92
145
|
midata.differential(chan1="EEG", chan2="EMG")
|
|
93
146
|
assert midata.channels[-1] == "EEG_EMG_DIFF"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{misleep-0.3.1 → misleep-0.3.2}/src/misleep/gui/uis/auto_stage_causalTransformer_dialog_ui.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|