misleep 0.2.7__tar.gz → 0.2.8__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.
Files changed (72) hide show
  1. {misleep-0.2.7 → misleep-0.2.8}/PKG-INFO +1 -1
  2. {misleep-0.2.7 → misleep-0.2.8}/misleep/config.ini +3 -3
  3. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/dialog.py +1 -2
  4. {misleep-0.2.7 → misleep-0.2.8}/misleep/io/annotation_io.py +4 -1
  5. {misleep-0.2.7 → misleep-0.2.8}/misleep/io/base.py +2 -1
  6. {misleep-0.2.7 → misleep-0.2.8}/misleep/io/signal_io.py +4 -1
  7. misleep-0.2.8/misleep/utils/signals.py +120 -0
  8. {misleep-0.2.7 → misleep-0.2.8}/misleep/viz/hypnogram.py +12 -1
  9. {misleep-0.2.7 → misleep-0.2.8}/misleep.egg-info/PKG-INFO +1 -1
  10. {misleep-0.2.7 → misleep-0.2.8}/setup.py +1 -1
  11. misleep-0.2.7/misleep/utils/signals.py +0 -73
  12. {misleep-0.2.7 → misleep-0.2.8}/LICENSE +0 -0
  13. {misleep-0.2.7 → misleep-0.2.8}/README.md +0 -0
  14. {misleep-0.2.7 → misleep-0.2.8}/misleep/__init__.py +0 -0
  15. {misleep-0.2.7 → misleep-0.2.8}/misleep/__main__.py +0 -0
  16. {misleep-0.2.7 → misleep-0.2.8}/misleep/analysis/__init__.py +0 -0
  17. {misleep-0.2.7 → misleep-0.2.8}/misleep/analysis/auto_stage.py +0 -0
  18. {misleep-0.2.7 → misleep-0.2.8}/misleep/analysis/auto_stage_model/P30_EEG_F_lightgbm.pkl +0 -0
  19. {misleep-0.2.7 → misleep-0.2.8}/misleep/analysis/auto_stage_model/P30_EEG_P_lightgbm.pkl +0 -0
  20. {misleep-0.2.7 → misleep-0.2.8}/misleep/analysis/auto_stage_model/ado_EEG_F_lightgbm.pkl +0 -0
  21. {misleep-0.2.7 → misleep-0.2.8}/misleep/analysis/auto_stage_model/ado_EEG_P_lightgbm.pkl +0 -0
  22. {misleep-0.2.7 → misleep-0.2.8}/misleep/analysis/auto_stage_model/adult_EEG_F_lightgbm.pkl +0 -0
  23. {misleep-0.2.7 → misleep-0.2.8}/misleep/analysis/auto_stage_model/adult_EEG_P_lightgbm.pkl +0 -0
  24. {misleep-0.2.7 → misleep-0.2.8}/misleep/analysis/detection.py +0 -0
  25. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/__init__.py +0 -0
  26. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/about.py +0 -0
  27. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/main_window.py +0 -0
  28. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/resources/__init__.py +0 -0
  29. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/resources/entire_logo.png +0 -0
  30. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/resources/logo.png +0 -0
  31. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/resources/misleep.py +0 -0
  32. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/resources/misleep.qrc +0 -0
  33. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/show.py +0 -0
  34. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/spec_window.py +0 -0
  35. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/thread.py +0 -0
  36. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/uis/SWA_detect_dialog_ui.py +0 -0
  37. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/uis/__init__.py +0 -0
  38. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/uis/about_ui.py +0 -0
  39. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/uis/auto_stage_dialog_ui.py +0 -0
  40. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/uis/horizontal_line_dialog_ui.py +0 -0
  41. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/uis/label_dialog_ui.py +0 -0
  42. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/uis/main_window_ui.py +0 -0
  43. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/uis/save_data_dialog_ui.py +0 -0
  44. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/uis/spec_window_ui.py +0 -0
  45. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/uis/spindle_detect_dialog_ui.py +0 -0
  46. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/uis/state_spectral_dialog_ui.py +0 -0
  47. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/uis/transfer_result_dialog_ui.py +0 -0
  48. {misleep-0.2.7 → misleep-0.2.8}/misleep/gui/utils.py +0 -0
  49. {misleep-0.2.7 → misleep-0.2.8}/misleep/io/__init__.py +0 -0
  50. {misleep-0.2.7 → misleep-0.2.8}/misleep/preprocessing/__init__.py +0 -0
  51. {misleep-0.2.7 → misleep-0.2.8}/misleep/preprocessing/channel.py +0 -0
  52. {misleep-0.2.7 → misleep-0.2.8}/misleep/preprocessing/signals.py +0 -0
  53. {misleep-0.2.7 → misleep-0.2.8}/misleep/preprocessing/spectral.py +0 -0
  54. {misleep-0.2.7 → misleep-0.2.8}/misleep/utils/__init__.py +0 -0
  55. {misleep-0.2.7 → misleep-0.2.8}/misleep/utils/annotation.py +0 -0
  56. {misleep-0.2.7 → misleep-0.2.8}/misleep/utils/logger_handler.py +0 -0
  57. {misleep-0.2.7 → misleep-0.2.8}/misleep/utils/self_antropy.py +0 -0
  58. {misleep-0.2.7 → misleep-0.2.8}/misleep/viz/__init__.py +0 -0
  59. {misleep-0.2.7 → misleep-0.2.8}/misleep/viz/signals.py +0 -0
  60. {misleep-0.2.7 → misleep-0.2.8}/misleep/viz/spectral.py +0 -0
  61. {misleep-0.2.7 → misleep-0.2.8}/misleep.egg-info/SOURCES.txt +0 -0
  62. {misleep-0.2.7 → misleep-0.2.8}/misleep.egg-info/dependency_links.txt +0 -0
  63. {misleep-0.2.7 → misleep-0.2.8}/misleep.egg-info/requires.txt +0 -0
  64. {misleep-0.2.7 → misleep-0.2.8}/misleep.egg-info/top_level.txt +0 -0
  65. {misleep-0.2.7 → misleep-0.2.8}/setup.cfg +0 -0
  66. {misleep-0.2.7 → misleep-0.2.8}/test/test_annotation_io.py +0 -0
  67. {misleep-0.2.7 → misleep-0.2.8}/test/test_loadmat73.py +0 -0
  68. {misleep-0.2.7 → misleep-0.2.8}/test/test_midata.py +0 -0
  69. {misleep-0.2.7 → misleep-0.2.8}/test/test_show.py +0 -0
  70. {misleep-0.2.7 → misleep-0.2.8}/test/test_signal_io.py +0 -0
  71. {misleep-0.2.7 → misleep-0.2.8}/test/test_signals_viz.py +0 -0
  72. {misleep-0.2.7 → misleep-0.2.8}/test/test_spectral_viz.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: misleep
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: MiSleep: Mice Sleep EEG/EMG visualization, scoring and analysis.
5
5
  Home-page: https://github.com/BryanWang0702/MiSleep/
6
6
  Download-URL: https://github.com/BryanWang0702/MiSleep/
@@ -1,6 +1,6 @@
1
1
  [gui]
2
- version = v0.2.7
3
- updatetime = 2025/3/25
2
+ version = v0.2.8
3
+ updatetime = 2025/4/1
4
4
  marker = ['good', 'first REM', 'WindEEG', 'W-R ', 'maker']
5
5
  startend = ['burst-supression', 'REM', 'Wake', 'Spindle', 'SWA', 'start end label', 'start end label']
6
6
  statemap = {"1": "NREM", "2": "REM", "3": "Wake", "4": "INIT", "5": "IS", "6": "MicroArousal"}
@@ -9,5 +9,5 @@ startendcolor = {"NREM": "orange", "REM": "skyblue", "Wake": "red"}
9
9
  statecolorbgalpha = 0.1
10
10
  markerlinecolor = "red"
11
11
  startendlinecolor = "blue"
12
- openpath = //172.16.41.188/wangtianyi/Sleep architecture/Female/Sham/P30/DOB250214_250318_28/annotation.txt
12
+ openpath = D:
13
13
 
@@ -403,7 +403,7 @@ class stateSpectral_dialog(QDialog, Ui_StateSpectralDialog):
403
403
  Wake_hour_spec = []
404
404
  if self.HourSegmentCheckBox.isChecked():
405
405
  for sec in range(0, end_sec-start_sec, 3600):
406
- sleep_state = mianno.sleep_state[sec:sec+3600]
406
+ sleep_state = mianno.sleep_state[start_sec+sec: start_sec+sec+3600]
407
407
  sleep_state = lst2group([[idx+sec, each] for idx, each in enumerate(sleep_state)])
408
408
 
409
409
  # Merge 4 states' data
@@ -466,7 +466,6 @@ class stateSpectral_dialog(QDialog, Ui_StateSpectralDialog):
466
466
  Init_figure.savefig(fd + '/Init_spectrum.pdf')
467
467
 
468
468
  writer.close()
469
-
470
469
  QMessageBox.about(self, "Info", "Spectral analysis finished")
471
470
 
472
471
  def okEvent(self):
@@ -6,7 +6,6 @@
6
6
  @Date: 2024/3/6
7
7
  @Description: Annotation io, default is for MiSleep annotation, `NAME.txt`
8
8
  """
9
- from misleep.io.base import MiAnnotation
10
9
  from misleep.utils.annotation import marker2mianno, start_end2mianno, lst2group, sleep_state2mianno, transfer_time
11
10
  import pandas as pd
12
11
 
@@ -43,6 +42,8 @@ def load_misleep_anno(file_path, state_map=None):
43
42
 
44
43
  sleep_state = annotation[sleep_state_idx + 1:]
45
44
  sleep_state = sleep_state2mianno(sleep_state)
45
+
46
+ from misleep.io.base import MiAnnotation
46
47
 
47
48
  return MiAnnotation(sleep_state=sleep_state, start_end=start_end, marker=marker, state_map=state_map)
48
49
 
@@ -62,6 +63,8 @@ def load_bio_anno(file_path):
62
63
  }
63
64
 
64
65
  state_list = [state_map[each] for each in state_list]
66
+
67
+ from misleep.io.base import MiAnnotation
65
68
  return MiAnnotation(sleep_state=state_list, marker=[], start_end=[])
66
69
 
67
70
 
@@ -9,7 +9,7 @@
9
9
  import math
10
10
 
11
11
  import numpy as np
12
- from misleep.utils.signals import signal_filter
12
+
13
13
 
14
14
 
15
15
  class MiData:
@@ -143,6 +143,7 @@ class MiData:
143
143
  low : float
144
144
  high : float
145
145
  """
146
+ from misleep.utils.signals import signal_filter
146
147
  if chans is None or not isinstance(chans, list):
147
148
  raise TypeError(f"'chans' should be a list of channel names, got {type(chans)}")
148
149
 
@@ -13,7 +13,6 @@
13
13
  from hdf5storage import savemat
14
14
  import pyedflib
15
15
  import datetime
16
- from misleep.io.base import MiData
17
16
  from misleep.utils.logger_handler import logger
18
17
 
19
18
 
@@ -40,6 +39,8 @@ def load_mat(data_path):
40
39
 
41
40
  from scipy.io import loadmat as scipy_loadmat
42
41
  from mat73 import loadmat as mat73_loadmat
42
+
43
+ from misleep.io.base import MiData
43
44
 
44
45
  try:
45
46
  # Use scipy to load
@@ -183,6 +184,8 @@ def load_edf(data_path):
183
184
  """
184
185
 
185
186
  signals, signal_headers, meta = pyedflib.highlevel.read_edf(edf_file=data_path)
187
+
188
+ from misleep.io.base import MiData
186
189
 
187
190
  return MiData(signals=signals,
188
191
  channels=[each['label'] for each in signal_headers],
@@ -0,0 +1,120 @@
1
+ # -*- coding: UTF-8 -*-
2
+ """
3
+ @Project: misleep
4
+ @File: signals.py
5
+ @Author: Xueqiang Wang
6
+ @Date: 2024/2/29
7
+ @Description:
8
+ """
9
+ import numpy as np
10
+ from scipy import signal
11
+ from copy import deepcopy
12
+ from misleep.io.base import MiData
13
+ from misleep.utils.annotation import lst2group
14
+
15
+
16
+ def signal_filter(data, sf=256., btype='lowpass', low=0.5, high=30.):
17
+ """
18
+ Filter the signal data, use butter filter in scipy
19
+
20
+ Parameters
21
+ ----------
22
+ data : ndarray
23
+ 1D array. Signal data need to be filtered.
24
+ sf : float
25
+ Sampling frequency of signal data. Default is 305.
26
+ btype : {'lowpass', 'highpass', 'bandpass'}, optional
27
+ The type of filter. Default is 'lowpass'.
28
+ low : float
29
+ Higher than this frequency can pass, used in 'highpass' and 'bandpass'
30
+ filter. Default is 0.5.
31
+ high : float
32
+ Lower than this frequency can pass, used in 'lowpass' and 'bandpass'
33
+ filter. Default is 30.
34
+
35
+ Returns
36
+ ----------
37
+ filtered_data : 1D-array
38
+ Filtered data of signal data using butter filter
39
+ fname : str
40
+
41
+ """
42
+ if not isinstance(sf, (int, float)):
43
+ raise TypeError(f"Sample frequency should be a float, got {type(sf)}")
44
+
45
+ if not isinstance(low, (int, float)):
46
+ raise TypeError(f"Low threshold should be a float, got {type(sf)}")
47
+
48
+ if not isinstance(high, (int, float)):
49
+ raise TypeError(f"high threshold should be a float, got {type(sf)}")
50
+
51
+ if btype == 'lowpass':
52
+ fnorm = high / (.5 * sf)
53
+ fname = f"{btype}_{high}"
54
+ elif btype == 'highpass':
55
+ fnorm = low / (.5 * sf)
56
+ fname = f"{btype}_{low}"
57
+ elif btype == 'bandpass':
58
+ fnorm = np.divide([low, high], .5 * sf)
59
+ fname = f"{btype}_{low}_{high}"
60
+ elif btype == 'bandstop':
61
+ fnorm = np.divide([low, high], .5 * sf)
62
+ fname = f"{btype}_{low}_{high}"
63
+ else:
64
+ raise ValueError("'%s' is an invalid type for filter, "
65
+ "you can only choose 'lowpass', 'highpass', 'bandpass' or 'bandstop'"
66
+ % btype)
67
+
68
+ # Use irrfilter of scipy.signal to construct a filter
69
+ b, a = signal.iirfilter(N=3, Wn=fnorm, btype=btype, analog=False,
70
+ output='ba', ftype='butter', fs=None)
71
+
72
+ filtered_data = signal.filtfilt(b=b, a=a, x=data)
73
+
74
+ return filtered_data, fname
75
+
76
+
77
+ def crop_state_data(midata, mianno):
78
+ """Crop the data with annotation into different state data, typically seperate the data into NREM data, REM data, Wake and Init data
79
+ Apply this to every channels
80
+ """
81
+ # Get the sleep state data
82
+ sleep_state = deepcopy(mianno.sleep_state)
83
+ sleep_state = lst2group([[idx, each] for idx, each in enumerate(sleep_state)])
84
+ signals = deepcopy(midata.signals)
85
+ NREM_signals = []
86
+ REM_signals = []
87
+ Wake_signals = []
88
+ Init_signals = []
89
+
90
+ for idx, signal in enumerate(signals):
91
+ sf = midata.sf[idx]
92
+
93
+ NREM_data = [signal[int(each[0]*sf): int(each[1]*sf)]
94
+ for each in sleep_state if each[2] == 1]
95
+ NREM_data = np.array([element for sublist in NREM_data for element in sublist])
96
+ NREM_signals.append(NREM_data)
97
+
98
+ REM_data = [signal[int(each[0]*sf): int(each[1]*sf)]
99
+ for each in sleep_state if each[2] == 2]
100
+ REM_data = np.array([element for sublist in REM_data for element in sublist])
101
+ REM_signals.append(REM_data)
102
+
103
+ Wake_data = [signal[int(each[0]*sf): int(each[1]*sf)]
104
+ for each in sleep_state if each[2] == 3]
105
+ Wake_data = np.array([element for sublist in Wake_data for element in sublist])
106
+ Wake_signals.append(Wake_data)
107
+
108
+ Init_data = [signal[int(each[0]*sf): int(each[1]*sf)]
109
+ for each in sleep_state if each[2] == 4]
110
+ Init_data = np.array([element for sublist in Init_data for element in sublist])
111
+ Init_signals.append(Init_data)
112
+
113
+ NREM_data = MiData(signals=NREM_signals, channels=midata.channels, sf=midata.sf, time=midata.time, describe='NREM cropped data')
114
+ REM_data = MiData(signals=REM_signals, channels=midata.channels, sf=midata.sf, time=midata.time, describe='REM cropped data')
115
+ Wake_data = MiData(signals=Wake_signals, channels=midata.channels, sf=midata.sf, time=midata.time, describe='Wake cropped data')
116
+ Init_data = MiData(signals=Init_signals, channels=midata.channels, sf=midata.sf, time=midata.time, describe='Init cropped data')
117
+
118
+ return NREM_data, REM_data, Wake_data, Init_data
119
+
120
+
@@ -11,7 +11,7 @@ import matplotlib.pyplot as plt
11
11
  import matplotlib
12
12
 
13
13
 
14
- def plot_hypno(sleep_state, state_map=None):
14
+ def plot_hypno(sleep_state, state_map=None, time_range=[0, -1]):
15
15
  """
16
16
  Draw hypnogram with sleep_state list
17
17
 
@@ -21,10 +21,21 @@ def plot_hypno(sleep_state, state_map=None):
21
21
  List of sleep state, should be integers, and use state_map map to contents
22
22
  state_map : dict
23
23
  Dict of mapping from sleep state content to it's meaning
24
+ time_range : list
25
+ Time range to plot the hypnogram
24
26
  """
25
27
 
26
28
  if not isinstance(sleep_state, list):
27
29
  raise TypeError(f"'sleep_state' should be a list, got {type(sleep_state)}")
30
+
31
+ try:
32
+ if time_range != [0, -1]:
33
+ sleep_state_ = sleep_state[time_range[0]:time_range[1]]
34
+ except Exception as e:
35
+ print("Invalid time range, plot as default")
36
+ sleep_state_ = sleep_state
37
+
38
+ sleep_state = sleep_state_
28
39
 
29
40
  if state_map is None:
30
41
  state_map = {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: misleep
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: MiSleep: Mice Sleep EEG/EMG visualization, scoring and analysis.
5
5
  Home-page: https://github.com/BryanWang0702/MiSleep/
6
6
  Download-URL: https://github.com/BryanWang0702/MiSleep/
@@ -11,7 +11,7 @@ MAINTAINER_EMAIL = "swang@gmail.com"
11
11
  URL = "https://github.com/BryanWang0702/MiSleep/"
12
12
  LICENSE = "BSD (3-clause)"
13
13
  DOWNLOAD_URL = "https://github.com/BryanWang0702/MiSleep/"
14
- VERSION = "0.2.7"
14
+ VERSION = "0.2.8"
15
15
 
16
16
  INSTALL_REQUIRES = [
17
17
  "numpy>=1.18.1",
@@ -1,73 +0,0 @@
1
- # -*- coding: UTF-8 -*-
2
- """
3
- @Project: misleep
4
- @File: signals.py
5
- @Author: Xueqiang Wang
6
- @Date: 2024/2/29
7
- @Description:
8
- """
9
- import numpy as np
10
- from scipy import signal
11
-
12
-
13
- def signal_filter(data, sf=256., btype='lowpass', low=0.5, high=30.):
14
- """
15
- Filter the signal data, use butter filter in scipy
16
-
17
- Parameters
18
- ----------
19
- data : ndarray
20
- 1D array. Signal data need to be filtered.
21
- sf : float
22
- Sampling frequency of signal data. Default is 305.
23
- btype : {'lowpass', 'highpass', 'bandpass'}, optional
24
- The type of filter. Default is 'lowpass'.
25
- low : float
26
- Higher than this frequency can pass, used in 'highpass' and 'bandpass'
27
- filter. Default is 0.5.
28
- high : float
29
- Lower than this frequency can pass, used in 'lowpass' and 'bandpass'
30
- filter. Default is 30.
31
-
32
- Returns
33
- ----------
34
- filtered_data : 1D-array
35
- Filtered data of signal data using butter filter
36
- fname : str
37
-
38
- """
39
- if not isinstance(sf, (int, float)):
40
- raise TypeError(f"Sample frequency should be a float, got {type(sf)}")
41
-
42
- if not isinstance(low, (int, float)):
43
- raise TypeError(f"Low threshold should be a float, got {type(sf)}")
44
-
45
- if not isinstance(high, (int, float)):
46
- raise TypeError(f"high threshold should be a float, got {type(sf)}")
47
-
48
- if btype == 'lowpass':
49
- fnorm = high / (.5 * sf)
50
- fname = f"{btype}_{high}"
51
- elif btype == 'highpass':
52
- fnorm = low / (.5 * sf)
53
- fname = f"{btype}_{low}"
54
- elif btype == 'bandpass':
55
- fnorm = np.divide([low, high], .5 * sf)
56
- fname = f"{btype}_{low}_{high}"
57
- elif btype == 'bandstop':
58
- fnorm = np.divide([low, high], .5 * sf)
59
- fname = f"{btype}_{low}_{high}"
60
- else:
61
- raise ValueError("'%s' is an invalid type for filter, "
62
- "you can only choose 'lowpass', 'highpass', 'bandpass' or 'bandstop'"
63
- % btype)
64
-
65
- # Use irrfilter of scipy.signal to construct a filter
66
- b, a = signal.iirfilter(N=3, Wn=fnorm, btype=btype, analog=False,
67
- output='ba', ftype='butter', fs=None)
68
-
69
- filtered_data = signal.filtfilt(b=b, a=a, x=data)
70
-
71
- return filtered_data, fname
72
-
73
-
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