spectre-core 0.0.22__py3-none-any.whl → 0.0.24__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.
- spectre_core/__init__.py +5 -0
- spectre_core/_file_io/__init__.py +4 -4
- spectre_core/_file_io/file_handlers.py +60 -106
- spectre_core/batches/__init__.py +20 -3
- spectre_core/batches/_base.py +85 -134
- spectre_core/batches/_batches.py +55 -99
- spectre_core/batches/_factory.py +21 -20
- spectre_core/batches/_register.py +8 -8
- spectre_core/batches/plugins/_batch_keys.py +7 -6
- spectre_core/batches/plugins/_callisto.py +65 -97
- spectre_core/batches/plugins/_iq_stream.py +105 -169
- spectre_core/capture_configs/__init__.py +46 -17
- spectre_core/capture_configs/_capture_config.py +25 -52
- spectre_core/capture_configs/_capture_modes.py +8 -6
- spectre_core/capture_configs/_capture_templates.py +50 -110
- spectre_core/capture_configs/_parameters.py +37 -74
- spectre_core/capture_configs/_pconstraints.py +40 -40
- spectre_core/capture_configs/_pnames.py +36 -34
- spectre_core/capture_configs/_ptemplates.py +260 -347
- spectre_core/capture_configs/_pvalidators.py +99 -102
- spectre_core/config/__init__.py +19 -8
- spectre_core/config/_paths.py +25 -47
- spectre_core/config/_time_formats.py +6 -5
- spectre_core/exceptions.py +38 -0
- spectre_core/jobs/__init__.py +3 -6
- spectre_core/jobs/_duration.py +12 -0
- spectre_core/jobs/_jobs.py +72 -43
- spectre_core/jobs/_workers.py +55 -105
- spectre_core/logs/__init__.py +7 -2
- spectre_core/logs/_configure.py +13 -17
- spectre_core/logs/_decorators.py +6 -4
- spectre_core/logs/_logs.py +37 -89
- spectre_core/logs/_process_types.py +5 -3
- spectre_core/plotting/__init__.py +19 -3
- spectre_core/plotting/_base.py +112 -177
- spectre_core/plotting/_format.py +10 -8
- spectre_core/plotting/_panel_names.py +7 -5
- spectre_core/plotting/_panel_stack.py +138 -130
- spectre_core/plotting/_panels.py +152 -162
- spectre_core/post_processing/__init__.py +6 -3
- spectre_core/post_processing/_base.py +41 -55
- spectre_core/post_processing/_factory.py +14 -11
- spectre_core/post_processing/_post_processor.py +16 -12
- spectre_core/post_processing/_register.py +10 -7
- spectre_core/post_processing/plugins/_event_handler_keys.py +4 -3
- spectre_core/post_processing/plugins/_fixed_center_frequency.py +54 -47
- spectre_core/post_processing/plugins/_swept_center_frequency.py +199 -174
- spectre_core/receivers/__init__.py +9 -2
- spectre_core/receivers/_base.py +82 -148
- spectre_core/receivers/_factory.py +20 -30
- spectre_core/receivers/_register.py +7 -10
- spectre_core/receivers/_spec_names.py +17 -15
- spectre_core/receivers/plugins/_b200mini.py +47 -60
- spectre_core/receivers/plugins/_receiver_names.py +8 -6
- spectre_core/receivers/plugins/_rsp1a.py +44 -40
- spectre_core/receivers/plugins/_rspduo.py +59 -44
- spectre_core/receivers/plugins/_sdrplay_receiver.py +67 -83
- spectre_core/receivers/plugins/_test.py +136 -129
- spectre_core/receivers/plugins/_usrp.py +93 -85
- spectre_core/receivers/plugins/gr/__init__.py +1 -1
- spectre_core/receivers/plugins/gr/_base.py +14 -22
- spectre_core/receivers/plugins/gr/_rsp1a.py +53 -60
- spectre_core/receivers/plugins/gr/_rspduo.py +77 -89
- spectre_core/receivers/plugins/gr/_test.py +49 -57
- spectre_core/receivers/plugins/gr/_usrp.py +61 -59
- spectre_core/spectrograms/__init__.py +21 -13
- spectre_core/spectrograms/_analytical.py +108 -99
- spectre_core/spectrograms/_array_operations.py +39 -46
- spectre_core/spectrograms/_spectrogram.py +293 -324
- spectre_core/spectrograms/_transform.py +106 -73
- spectre_core/wgetting/__init__.py +1 -3
- spectre_core/wgetting/_callisto.py +87 -93
- {spectre_core-0.0.22.dist-info → spectre_core-0.0.24.dist-info}/METADATA +9 -23
- spectre_core-0.0.24.dist-info/RECORD +79 -0
- {spectre_core-0.0.22.dist-info → spectre_core-0.0.24.dist-info}/WHEEL +1 -1
- spectre_core-0.0.22.dist-info/RECORD +0 -78
- {spectre_core-0.0.22.dist-info → spectre_core-0.0.24.dist-info}/licenses/LICENSE +0 -0
- {spectre_core-0.0.22.dist-info → spectre_core-0.0.24.dist-info}/top_level.txt +0 -0
spectre_core/logs/_logs.py
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
4
4
|
|
5
5
|
from logging import getLogger
|
6
|
+
|
6
7
|
_LOGGER = getLogger(__name__)
|
7
8
|
|
8
9
|
import os
|
@@ -15,11 +16,8 @@ from spectre_core.config import get_logs_dir_path, TimeFormat
|
|
15
16
|
from ._process_types import ProcessType
|
16
17
|
|
17
18
|
|
18
|
-
def parse_log_base_file_name(
|
19
|
-
|
20
|
-
) -> Tuple[str, str, str]:
|
21
|
-
"""Parse the base file name of a log into a start time, process ID and process type.
|
22
|
-
"""
|
19
|
+
def parse_log_base_file_name(base_file_name: str) -> Tuple[str, str, str]:
|
20
|
+
"""Parse the base file name of a log into a start time, process ID and process type."""
|
23
21
|
file_name, _ = os.path.splitext(base_file_name)
|
24
22
|
log_start_time, pid, process_type = file_name.split("_")
|
25
23
|
return log_start_time, pid, process_type
|
@@ -27,12 +25,8 @@ def parse_log_base_file_name(
|
|
27
25
|
|
28
26
|
class Log(TextHandler):
|
29
27
|
"""Interface to read log files generated by `spectre`."""
|
30
|
-
|
31
|
-
|
32
|
-
start_time: str,
|
33
|
-
pid: str,
|
34
|
-
process_type: ProcessType
|
35
|
-
) -> None:
|
28
|
+
|
29
|
+
def __init__(self, start_time: str, pid: str, process_type: ProcessType) -> None:
|
36
30
|
"""Initialise a `Log` instance.
|
37
31
|
|
38
32
|
:param start_time: The timestamp when the log file was created.
|
@@ -48,40 +42,32 @@ class Log(TextHandler):
|
|
48
42
|
base_file_name = f"{start_time}_{pid}_{process_type.value}"
|
49
43
|
|
50
44
|
super().__init__(parent_path, base_file_name, "log")
|
51
|
-
|
52
45
|
|
53
46
|
@property
|
54
|
-
def start_time(
|
55
|
-
self
|
56
|
-
) -> str:
|
47
|
+
def start_time(self) -> str:
|
57
48
|
"""The system time when the log was created."""
|
58
49
|
return self._start_time
|
59
|
-
|
60
50
|
|
61
51
|
@property
|
62
|
-
def pid(
|
63
|
-
self
|
64
|
-
) -> str:
|
52
|
+
def pid(self) -> str:
|
65
53
|
"""The ID of the process writing to the log file."""
|
66
54
|
return self._pid
|
67
|
-
|
68
55
|
|
69
56
|
@property
|
70
|
-
def process_type(
|
71
|
-
self
|
72
|
-
) -> str:
|
57
|
+
def process_type(self) -> str:
|
73
58
|
"""Indicates the type of process, as defined by `ProcessType`."""
|
74
59
|
return self._process_type
|
75
60
|
|
76
61
|
|
77
62
|
class Logs:
|
78
63
|
"""Filter and read a collection of logs generated by `spectre`."""
|
64
|
+
|
79
65
|
def __init__(
|
80
|
-
self,
|
81
|
-
process_type: Optional[ProcessType] = None,
|
82
|
-
year: Optional[int] = None,
|
83
|
-
month: Optional[int] = None,
|
84
|
-
day: Optional[int] = None
|
66
|
+
self,
|
67
|
+
process_type: Optional[ProcessType] = None,
|
68
|
+
year: Optional[int] = None,
|
69
|
+
month: Optional[int] = None,
|
70
|
+
day: Optional[int] = None,
|
85
71
|
) -> None:
|
86
72
|
"""Initialise a `Logs` instance.
|
87
73
|
|
@@ -91,81 +77,53 @@ class Logs:
|
|
91
77
|
:param day: Filter by the numeric day. Defaults to None.
|
92
78
|
"""
|
93
79
|
self._process_type = process_type.value if process_type is not None else None
|
94
|
-
|
80
|
+
|
95
81
|
self._log_map: dict[str, Log] = OrderedDict()
|
96
82
|
self.set_date(year, month, day)
|
97
83
|
|
98
|
-
|
99
84
|
@property
|
100
|
-
def process_type(
|
101
|
-
self
|
102
|
-
) -> Optional[str]:
|
85
|
+
def process_type(self) -> Optional[str]:
|
103
86
|
"""Indicates the type of process, as defined by `ProcessType`."""
|
104
87
|
return self._process_type
|
105
|
-
|
106
88
|
|
107
89
|
@property
|
108
|
-
def year(
|
109
|
-
self
|
110
|
-
) -> Optional[int]:
|
90
|
+
def year(self) -> Optional[int]:
|
111
91
|
"""Filter by the numeric year."""
|
112
92
|
return self._year
|
113
93
|
|
114
|
-
|
115
|
-
|
116
|
-
def month(
|
117
|
-
self
|
118
|
-
) -> Optional[int]:
|
94
|
+
@property
|
95
|
+
def month(self) -> Optional[int]:
|
119
96
|
"""Filter by the numeric month."""
|
120
97
|
return self._month
|
121
|
-
|
122
98
|
|
123
99
|
@property
|
124
|
-
def day(
|
125
|
-
self
|
126
|
-
) -> Optional[int]:
|
100
|
+
def day(self) -> Optional[int]:
|
127
101
|
"""Filter by the numeric day."""
|
128
102
|
return self._day
|
129
103
|
|
130
|
-
|
131
104
|
@property
|
132
|
-
def logs_dir_path(
|
133
|
-
self
|
134
|
-
) -> str:
|
105
|
+
def logs_dir_path(self) -> str:
|
135
106
|
"""The shared ancestral path for all the log files. `Logs` recursively searches
|
136
107
|
this directory to find all log files according to the date and process type."""
|
137
108
|
return get_logs_dir_path(self.year, self.month, self.day)
|
138
|
-
|
139
109
|
|
140
110
|
@property
|
141
|
-
def log_list(
|
142
|
-
self
|
143
|
-
) -> list[Log]:
|
111
|
+
def log_list(self) -> list[Log]:
|
144
112
|
"""A list of all log handlers representing files found within `logs_dir_path`."""
|
145
113
|
return list(self._log_map.values())
|
146
114
|
|
147
|
-
|
148
115
|
@property
|
149
|
-
def num_logs(
|
150
|
-
self
|
151
|
-
) -> int:
|
116
|
+
def num_logs(self) -> int:
|
152
117
|
"""The number of log files found within `logs_dir_path`."""
|
153
|
-
return len(self.log_list)
|
154
|
-
|
118
|
+
return len(self.log_list)
|
155
119
|
|
156
120
|
@property
|
157
|
-
def file_names(
|
158
|
-
self
|
159
|
-
) -> list[str]:
|
121
|
+
def file_names(self) -> list[str]:
|
160
122
|
"""A list of all log file names found within `logs_dir_path`."""
|
161
123
|
return list(self._log_map.keys())
|
162
124
|
|
163
|
-
|
164
125
|
def set_date(
|
165
|
-
self,
|
166
|
-
year: Optional[int],
|
167
|
-
month: Optional[int],
|
168
|
-
day: Optional[int]
|
126
|
+
self, year: Optional[int], month: Optional[int], day: Optional[int]
|
169
127
|
) -> None:
|
170
128
|
"""Reset `logs_dir_path` according to the numeric date, and refresh the list
|
171
129
|
of available log files.
|
@@ -179,36 +137,28 @@ class Logs:
|
|
179
137
|
self._day = day
|
180
138
|
self.update()
|
181
139
|
|
182
|
-
|
183
|
-
def update(
|
184
|
-
self
|
185
|
-
) -> None:
|
140
|
+
def update(self) -> None:
|
186
141
|
"""Perform a fresh search of all files in `logs_dir_path` for log files
|
187
142
|
according to the date and process type."""
|
188
143
|
log_files = [f for (_, _, files) in os.walk(self.logs_dir_path) for f in files]
|
189
144
|
|
190
145
|
for log_file in log_files:
|
191
|
-
|
146
|
+
|
192
147
|
log_start_time, pid, process_type = parse_log_base_file_name(log_file)
|
193
148
|
|
194
149
|
if self.process_type and process_type != self.process_type:
|
195
150
|
continue
|
196
151
|
|
197
|
-
self._log_map[log_file] = Log(
|
152
|
+
self._log_map[log_file] = Log(
|
153
|
+
log_start_time, pid, ProcessType(process_type)
|
154
|
+
)
|
198
155
|
|
199
156
|
self._log_map = OrderedDict(sorted(self._log_map.items()))
|
200
157
|
|
201
|
-
|
202
|
-
def __iter__(
|
203
|
-
self
|
204
|
-
) -> Iterator[Log]:
|
158
|
+
def __iter__(self) -> Iterator[Log]:
|
205
159
|
yield from self.log_list
|
206
160
|
|
207
|
-
|
208
|
-
def get_from_file_name(
|
209
|
-
self,
|
210
|
-
file_name: str
|
211
|
-
) -> Log:
|
161
|
+
def get_from_file_name(self, file_name: str) -> Log:
|
212
162
|
"""Retrieve a `Log` instance based on the log file name.
|
213
163
|
|
214
164
|
:param file_name: The name of the log file (with or without extension).
|
@@ -220,13 +170,11 @@ class Logs:
|
|
220
170
|
try:
|
221
171
|
return self._log_map[file_name]
|
222
172
|
except KeyError:
|
223
|
-
raise FileNotFoundError(
|
224
|
-
|
173
|
+
raise FileNotFoundError(
|
174
|
+
f"Log handler for file name '{file_name}' not found in log map"
|
175
|
+
)
|
225
176
|
|
226
|
-
def get_from_pid(
|
227
|
-
self,
|
228
|
-
pid: str
|
229
|
-
) -> Log:
|
177
|
+
def get_from_pid(self, pid: str) -> Log:
|
230
178
|
"""Retrieve a `Log` instance based on the process ID.
|
231
179
|
|
232
180
|
:param pid: The process ID to search for.
|
@@ -4,11 +4,13 @@
|
|
4
4
|
|
5
5
|
from enum import Enum
|
6
6
|
|
7
|
+
|
7
8
|
class ProcessType(Enum):
|
8
9
|
"""The origin of a `spectre` process.
|
9
|
-
|
10
|
+
|
10
11
|
:ivar USER: A process is one initiated directly by the user, or part of the main user session.
|
11
12
|
:ivar WORKER: A process is one which is created and managed internally by `spectre`.
|
12
13
|
"""
|
13
|
-
|
14
|
-
|
14
|
+
|
15
|
+
USER = "user"
|
16
|
+
WORKER = "worker"
|
@@ -5,9 +5,25 @@
|
|
5
5
|
"""An intuitive API for plotting spectrogram data."""
|
6
6
|
|
7
7
|
from ._format import PanelFormat
|
8
|
-
from .
|
8
|
+
from ._panel_names import PanelName
|
9
|
+
from ._base import BasePanel, BaseTimeSeriesPanel, XAxisType
|
10
|
+
from ._panels import (
|
11
|
+
SpectrogramPanel,
|
12
|
+
FrequencyCutsPanel,
|
13
|
+
TimeCutsPanel,
|
14
|
+
IntegralOverFrequencyPanel,
|
15
|
+
)
|
9
16
|
from ._panel_stack import PanelStack
|
10
17
|
|
11
18
|
__all__ = [
|
12
|
-
"
|
13
|
-
|
19
|
+
"BaseTimeSeriesPanel",
|
20
|
+
"PanelName",
|
21
|
+
"XAxisType",
|
22
|
+
"BasePanel",
|
23
|
+
"PanelFormat",
|
24
|
+
"PanelStack",
|
25
|
+
"SpectrogramPanel",
|
26
|
+
"FrequencyCutsPanel",
|
27
|
+
"TimeCutsPanel",
|
28
|
+
"IntegralOverFrequencyPanel",
|
29
|
+
]
|