accusleepy 0.8.0__py3-none-any.whl → 0.8.1__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.
- accusleepy/bouts.py +44 -36
- accusleepy/fileio.py +34 -22
- accusleepy/gui/images/primary_window.png +0 -0
- accusleepy/gui/main.py +10 -11
- accusleepy/gui/manual_scoring.py +4 -12
- {accusleepy-0.8.0.dist-info → accusleepy-0.8.1.dist-info}/METADATA +3 -5
- {accusleepy-0.8.0.dist-info → accusleepy-0.8.1.dist-info}/RECORD +8 -8
- {accusleepy-0.8.0.dist-info → accusleepy-0.8.1.dist-info}/WHEEL +0 -0
accusleepy/bouts.py
CHANGED
|
@@ -11,7 +11,7 @@ class Bout:
|
|
|
11
11
|
|
|
12
12
|
length: int # length, in number of epochs
|
|
13
13
|
start_index: int # index where bout starts
|
|
14
|
-
end_index: int # index where bout ends
|
|
14
|
+
end_index: int # index where bout ends (non-inclusive)
|
|
15
15
|
surrounding_state: int # brain state on both sides of the bout
|
|
16
16
|
|
|
17
17
|
|
|
@@ -41,6 +41,44 @@ def find_last_adjacent_bout(sorted_bouts: list[Bout], bout_index: int) -> int:
|
|
|
41
41
|
return bout_index
|
|
42
42
|
|
|
43
43
|
|
|
44
|
+
def find_short_bouts(
|
|
45
|
+
labels: np.array, min_epochs: int, brain_states: set[int]
|
|
46
|
+
) -> list[Bout]:
|
|
47
|
+
"""Locate all brain state bouts below a minimum length
|
|
48
|
+
|
|
49
|
+
:param labels: brain state labels (digits in the 0-9 range)
|
|
50
|
+
:param min_epochs: minimum number of epochs in a bout
|
|
51
|
+
:param brain_states: set of brain states in the labels
|
|
52
|
+
:return: list of Bout objects
|
|
53
|
+
"""
|
|
54
|
+
# convert labels to a string for regex search
|
|
55
|
+
# There is probably a regex that can find all patterns like ab+a
|
|
56
|
+
# without consuming each "a" but I haven't found it :(
|
|
57
|
+
label_string = "".join(labels.astype(str))
|
|
58
|
+
bouts = list()
|
|
59
|
+
for state in brain_states:
|
|
60
|
+
for other_state in brain_states:
|
|
61
|
+
if state == other_state:
|
|
62
|
+
continue
|
|
63
|
+
# get start and end indices of each bout
|
|
64
|
+
expression = (
|
|
65
|
+
f"(?<={other_state}){state}{{1,{min_epochs - 1}}}(?={other_state})"
|
|
66
|
+
)
|
|
67
|
+
matches = re.finditer(expression, label_string)
|
|
68
|
+
spans = [match.span() for match in matches]
|
|
69
|
+
|
|
70
|
+
for span in spans:
|
|
71
|
+
bouts.append(
|
|
72
|
+
Bout(
|
|
73
|
+
length=span[1] - span[0],
|
|
74
|
+
start_index=span[0],
|
|
75
|
+
end_index=span[1],
|
|
76
|
+
surrounding_state=other_state,
|
|
77
|
+
)
|
|
78
|
+
)
|
|
79
|
+
return bouts
|
|
80
|
+
|
|
81
|
+
|
|
44
82
|
def enforce_min_bout_length(
|
|
45
83
|
labels: np.array, epoch_length: int | float, min_bout_length: int | float
|
|
46
84
|
) -> np.array:
|
|
@@ -61,11 +99,9 @@ def enforce_min_bout_length(
|
|
|
61
99
|
:param min_bout_length: minimum bout length, in seconds
|
|
62
100
|
:return: updated brain state labels
|
|
63
101
|
"""
|
|
64
|
-
# if recording is very short
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if epoch_length == min_bout_length:
|
|
102
|
+
# if the recording is very short or the minimum bout length
|
|
103
|
+
# is one epoch long, don't change anything
|
|
104
|
+
if labels.size < 3 or epoch_length == min_bout_length:
|
|
69
105
|
return labels
|
|
70
106
|
|
|
71
107
|
# get minimum number of epochs in a bout
|
|
@@ -73,36 +109,8 @@ def enforce_min_bout_length(
|
|
|
73
109
|
# get set of states in the labels
|
|
74
110
|
brain_states = set(labels.tolist())
|
|
75
111
|
|
|
76
|
-
while True:
|
|
77
|
-
|
|
78
|
-
# There is probably a regex that can find all patterns like ab+a
|
|
79
|
-
# without consuming each "a" but I haven't found it :(
|
|
80
|
-
label_string = "".join(labels.astype(str))
|
|
81
|
-
|
|
82
|
-
bouts = list()
|
|
83
|
-
|
|
84
|
-
for state in brain_states:
|
|
85
|
-
for other_state in brain_states:
|
|
86
|
-
if state == other_state:
|
|
87
|
-
continue
|
|
88
|
-
# get start and end indices of each bout
|
|
89
|
-
expression = (
|
|
90
|
-
f"(?<={other_state}){state}{{1,{min_epochs - 1}}}(?={other_state})"
|
|
91
|
-
)
|
|
92
|
-
matches = re.finditer(expression, label_string)
|
|
93
|
-
spans = [match.span() for match in matches]
|
|
94
|
-
|
|
95
|
-
# if some bouts were found
|
|
96
|
-
for span in spans:
|
|
97
|
-
bouts.append(
|
|
98
|
-
Bout(
|
|
99
|
-
length=span[1] - span[0],
|
|
100
|
-
start_index=span[0],
|
|
101
|
-
end_index=span[1],
|
|
102
|
-
surrounding_state=other_state,
|
|
103
|
-
)
|
|
104
|
-
)
|
|
105
|
-
|
|
112
|
+
while True:
|
|
113
|
+
bouts = find_short_bouts(labels, min_epochs, brain_states)
|
|
106
114
|
if len(bouts) == 0:
|
|
107
115
|
break
|
|
108
116
|
|
accusleepy/fileio.py
CHANGED
|
@@ -29,6 +29,21 @@ class Hyperparameters:
|
|
|
29
29
|
training_epochs: int
|
|
30
30
|
|
|
31
31
|
|
|
32
|
+
@dataclass
|
|
33
|
+
class AccuSleePyConfig:
|
|
34
|
+
"""AccuSleePy configuration settings"""
|
|
35
|
+
|
|
36
|
+
brain_state_set: BrainStateSet
|
|
37
|
+
default_epoch_length: int | float
|
|
38
|
+
overwrite_setting: bool
|
|
39
|
+
save_confidence_setting: bool
|
|
40
|
+
min_bout_length: int | float
|
|
41
|
+
emg_filter: EMGFilter
|
|
42
|
+
hyperparameters: Hyperparameters
|
|
43
|
+
epochs_to_show: int
|
|
44
|
+
autoscroll_state: bool
|
|
45
|
+
|
|
46
|
+
|
|
32
47
|
@dataclass
|
|
33
48
|
class Recording:
|
|
34
49
|
"""Store information about a recording"""
|
|
@@ -111,20 +126,11 @@ def save_labels(
|
|
|
111
126
|
pd.DataFrame({c.BRAIN_STATE_COL: labels}).to_csv(filename, index=False)
|
|
112
127
|
|
|
113
128
|
|
|
114
|
-
def load_config() ->
|
|
115
|
-
BrainStateSet,
|
|
116
|
-
int | float,
|
|
117
|
-
bool,
|
|
118
|
-
bool,
|
|
119
|
-
int | float,
|
|
120
|
-
EMGFilter,
|
|
121
|
-
Hyperparameters,
|
|
122
|
-
int,
|
|
123
|
-
bool,
|
|
124
|
-
]:
|
|
129
|
+
def load_config() -> AccuSleePyConfig:
|
|
125
130
|
"""Load configuration file with brain state options
|
|
126
131
|
|
|
127
|
-
:return:
|
|
132
|
+
:return: AccuSleePyConfig containing the following:
|
|
133
|
+
set of brain state options,
|
|
128
134
|
default epoch length,
|
|
129
135
|
default overwrite setting,
|
|
130
136
|
default confidence score output setting,
|
|
@@ -139,15 +145,21 @@ def load_config() -> tuple[
|
|
|
139
145
|
) as f:
|
|
140
146
|
data = json.load(f)
|
|
141
147
|
|
|
142
|
-
return (
|
|
143
|
-
BrainStateSet(
|
|
148
|
+
return AccuSleePyConfig(
|
|
149
|
+
brain_state_set=BrainStateSet(
|
|
144
150
|
[BrainState(**b) for b in data[BRAIN_STATES_KEY]], c.UNDEFINED_LABEL
|
|
145
151
|
),
|
|
146
|
-
data[c.DEFAULT_EPOCH_LENGTH_KEY],
|
|
147
|
-
data.get(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
152
|
+
default_epoch_length=data[c.DEFAULT_EPOCH_LENGTH_KEY],
|
|
153
|
+
overwrite_setting=data.get(
|
|
154
|
+
c.DEFAULT_OVERWRITE_KEY, c.DEFAULT_OVERWRITE_SETTING
|
|
155
|
+
),
|
|
156
|
+
save_confidence_setting=data.get(
|
|
157
|
+
c.DEFAULT_CONFIDENCE_SETTING_KEY, c.DEFAULT_CONFIDENCE_SETTING
|
|
158
|
+
),
|
|
159
|
+
min_bout_length=data.get(
|
|
160
|
+
c.DEFAULT_MIN_BOUT_LENGTH_KEY, c.DEFAULT_MIN_BOUT_LENGTH
|
|
161
|
+
),
|
|
162
|
+
emg_filter=EMGFilter(
|
|
151
163
|
**data.get(
|
|
152
164
|
c.EMG_FILTER_KEY,
|
|
153
165
|
{
|
|
@@ -157,7 +169,7 @@ def load_config() -> tuple[
|
|
|
157
169
|
},
|
|
158
170
|
)
|
|
159
171
|
),
|
|
160
|
-
Hyperparameters(
|
|
172
|
+
hyperparameters=Hyperparameters(
|
|
161
173
|
**data.get(
|
|
162
174
|
c.HYPERPARAMETERS_KEY,
|
|
163
175
|
{
|
|
@@ -168,8 +180,8 @@ def load_config() -> tuple[
|
|
|
168
180
|
},
|
|
169
181
|
)
|
|
170
182
|
),
|
|
171
|
-
data.get(c.EPOCHS_TO_SHOW_KEY, c.DEFAULT_EPOCHS_TO_SHOW),
|
|
172
|
-
data.get(c.AUTOSCROLL_KEY, c.DEFAULT_AUTOSCROLL_STATE),
|
|
183
|
+
epochs_to_show=data.get(c.EPOCHS_TO_SHOW_KEY, c.DEFAULT_EPOCHS_TO_SHOW),
|
|
184
|
+
autoscroll_state=data.get(c.AUTOSCROLL_KEY, c.DEFAULT_AUTOSCROLL_STATE),
|
|
173
185
|
)
|
|
174
186
|
|
|
175
187
|
|
|
Binary file
|
accusleepy/gui/main.py
CHANGED
|
@@ -113,17 +113,16 @@ class AccuSleepWindow(QMainWindow):
|
|
|
113
113
|
self.setWindowTitle("AccuSleePy")
|
|
114
114
|
|
|
115
115
|
# fill in settings tab
|
|
116
|
-
(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
) = load_config()
|
|
116
|
+
config = load_config()
|
|
117
|
+
self.brain_state_set = config.brain_state_set
|
|
118
|
+
self.epoch_length = config.default_epoch_length
|
|
119
|
+
self.only_overwrite_undefined = config.overwrite_setting
|
|
120
|
+
self.save_confidence_scores = config.save_confidence_setting
|
|
121
|
+
self.min_bout_length = config.min_bout_length
|
|
122
|
+
self.emg_filter = config.emg_filter
|
|
123
|
+
self.hyperparameters = config.hyperparameters
|
|
124
|
+
self.default_epochs_to_show = config.epochs_to_show
|
|
125
|
+
self.default_autoscroll_state = config.autoscroll_state
|
|
127
126
|
|
|
128
127
|
self.settings_widgets = None
|
|
129
128
|
self.initialize_settings_tab()
|
accusleepy/gui/manual_scoring.py
CHANGED
|
@@ -139,18 +139,10 @@ class ManualScoringWindow(QDialog):
|
|
|
139
139
|
self.ui.setupUi(self)
|
|
140
140
|
self.setWindowTitle("AccuSleePy manual scoring window")
|
|
141
141
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
_,
|
|
147
|
-
_,
|
|
148
|
-
_,
|
|
149
|
-
_,
|
|
150
|
-
_,
|
|
151
|
-
self.epochs_to_show,
|
|
152
|
-
self.autoscroll_state,
|
|
153
|
-
) = load_config()
|
|
142
|
+
config = load_config()
|
|
143
|
+
self.brain_state_set = config.brain_state_set
|
|
144
|
+
self.epochs_to_show = config.epochs_to_show
|
|
145
|
+
self.autoscroll_state = config.autoscroll_state
|
|
154
146
|
|
|
155
147
|
# find the set of y-axis locations of valid brain state labels
|
|
156
148
|
self.label_display_options = convert_labels(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: accusleepy
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.1
|
|
4
4
|
Summary: Python implementation of AccuSleep
|
|
5
5
|
License: GPL-3.0-only
|
|
6
6
|
Author: Zeke Barger
|
|
@@ -80,6 +80,7 @@ please consult the [developer guide](accusleepy/gui/text/dev_guide.md).
|
|
|
80
80
|
|
|
81
81
|
## Changelog
|
|
82
82
|
|
|
83
|
+
- 0.8.1: Increased test coverage
|
|
83
84
|
- 0.8.0: More configurable settings, visual improvements
|
|
84
85
|
- 0.7.1-0.7.3: Bugfixes, code cleanup
|
|
85
86
|
- 0.7.0: More settings can be configured in the UI
|
|
@@ -87,10 +88,7 @@ please consult the [developer guide](accusleepy/gui/text/dev_guide.md).
|
|
|
87
88
|
since the new calibration feature will make the confidence scores more accurate.
|
|
88
89
|
- 0.5.0: Performance improvements
|
|
89
90
|
- 0.4.5: Added support for python 3.13, **removed support for python 3.10.**
|
|
90
|
-
- 0.4.4:
|
|
91
|
-
- 0.4.3: Improved unit tests and user manuals
|
|
92
|
-
- 0.4.0: Improved visuals and user manuals
|
|
93
|
-
- 0.1.0-0.3.1: Early development versions
|
|
91
|
+
- 0.1.0-0.4.4: Early development versions
|
|
94
92
|
|
|
95
93
|
## Screenshots
|
|
96
94
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
accusleepy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
accusleepy/__main__.py,sha256=dKzl2N2Hg9lD264CWYNxThRyDKzWwyMwHRXmJxOmMis,104
|
|
3
|
-
accusleepy/bouts.py,sha256=
|
|
3
|
+
accusleepy/bouts.py,sha256=biJEzCjMQR-RTlQcfeomkp6NxcA5FXkhE8Kp2XyL4P4,6039
|
|
4
4
|
accusleepy/brain_state_set.py,sha256=fRkrArHLIbEKimub804yt_mUXoyfsjJEfiJnTjeCMkY,3233
|
|
5
5
|
accusleepy/classification.py,sha256=mF35xMrD9QXGldSnl3vkdHbm7CAptPUNjHxUA_agOTA,9778
|
|
6
6
|
accusleepy/config.json,sha256=VmUFsiGD1ymEyjdzqeM5nTp8jWvDI-DIxLy1_92nueo,875
|
|
7
7
|
accusleepy/constants.py,sha256=62mmsr1NKzF-psS-9esuAE65kAcPL6o8v9UXQEvb5yc,2983
|
|
8
|
-
accusleepy/fileio.py,sha256
|
|
8
|
+
accusleepy/fileio.py,sha256=-aEgp2oonjQKRizVI1uI5CGknnBOxE6HG0DzxDYbSkM,8512
|
|
9
9
|
accusleepy/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
accusleepy/gui/icons/brightness_down.png,sha256=PLT1fb83RHIhSRuU7MMMx0G7oJAY7o9wUcnqM8veZfM,12432
|
|
11
11
|
accusleepy/gui/icons/brightness_up.png,sha256=64GnUqgPvN5xZ6Um3wOzwqvUmdAWYZT6eFmWpBsHyks,12989
|
|
@@ -18,11 +18,11 @@ accusleepy/gui/icons/save.png,sha256=J3EA8iU1BqLYRSsrq_OdoZlqrv2yfL7oV54DklTy_DI
|
|
|
18
18
|
accusleepy/gui/icons/up_arrow.png,sha256=V9yF9t1WgjPaUu-mF1YGe_DfaRHg2dUpR_sUVVcvVvY,3329
|
|
19
19
|
accusleepy/gui/icons/zoom_in.png,sha256=MFWnKZp7Rvh4bLPq4Cqo4sB_jQYedUUtT8-ZO8tNYyc,13589
|
|
20
20
|
accusleepy/gui/icons/zoom_out.png,sha256=IB8Jecb3i0U4qjWRR46ridjLpvLCSe7PozBaLqQqYSw,13055
|
|
21
|
-
accusleepy/gui/images/primary_window.png,sha256=
|
|
21
|
+
accusleepy/gui/images/primary_window.png,sha256=yRGUdIcByF8DtPtDWqjmnQ8J3IHKtmijBsT7N9e1Ij0,595764
|
|
22
22
|
accusleepy/gui/images/viewer_window.png,sha256=b_B7m9WSLMAOzNjctq76SyekO1WfC6qYZVNnYfhjPe8,977197
|
|
23
23
|
accusleepy/gui/images/viewer_window_annotated.png,sha256=uMNUmsZIdzDlQpyoiS3lJGoWlg_T325Oj5hDZhM3Y14,146817
|
|
24
|
-
accusleepy/gui/main.py,sha256=
|
|
25
|
-
accusleepy/gui/manual_scoring.py,sha256=
|
|
24
|
+
accusleepy/gui/main.py,sha256=cZQH0qJ_mykeQP7eadc1yzFHYeDwbRngrR4_H1wMxWY,58438
|
|
25
|
+
accusleepy/gui/manual_scoring.py,sha256=QCFF-CIU6nh26NB8Z9ktohCk8p7ola2hgjazD-OrK_o,40697
|
|
26
26
|
accusleepy/gui/mplwidget.py,sha256=rJSTtWmLjHn8r3c9Kb23Rc4XzXl3i9B-JrjNjjlNnmQ,13492
|
|
27
27
|
accusleepy/gui/primary_window.py,sha256=qqV-GAC3BgOus1lJMOg2U4AGQbhy35zLMyN8Q7ouTd8,141479
|
|
28
28
|
accusleepy/gui/primary_window.ui,sha256=2mD0G6b8bsyyUvMCUosQ0K-nAzMA2iiP3yMpeh9INcQ,208209
|
|
@@ -38,6 +38,6 @@ accusleepy/multitaper.py,sha256=D5-iglwkFBRciL5tKSNcunMtcq0rM3zHwRHUVPgem1U,2567
|
|
|
38
38
|
accusleepy/signal_processing.py,sha256=47fEAx8Aqqkiqix1ai2YEK9Fhq6UHoQcwAcOi-a8ewo,16834
|
|
39
39
|
accusleepy/temperature_scaling.py,sha256=glvPcvxHpBdFjwjGfZdNku9L_BozycEmdqZhKKUCCNg,5749
|
|
40
40
|
accusleepy/validation.py,sha256=VpLWK-wD5tCU6lTBG3KYgTi3PWGuYh6NitMgMoMH8JM,4434
|
|
41
|
-
accusleepy-0.8.
|
|
42
|
-
accusleepy-0.8.
|
|
43
|
-
accusleepy-0.8.
|
|
41
|
+
accusleepy-0.8.1.dist-info/METADATA,sha256=29kPvzKr2ykosWwidIt6FKrjvIY-m88Ui9GQPoQPN-g,4710
|
|
42
|
+
accusleepy-0.8.1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
43
|
+
accusleepy-0.8.1.dist-info/RECORD,,
|
|
File without changes
|