spectre-core 0.0.9__py3-none-any.whl → 0.0.10__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 +0 -3
- spectre_core/_file_io/__init__.py +15 -0
- spectre_core/_file_io/file_handlers.py +128 -0
- spectre_core/capture_configs/__init__.py +29 -0
- spectre_core/capture_configs/_capture_config.py +85 -0
- spectre_core/capture_configs/_capture_templates.py +222 -0
- spectre_core/capture_configs/_parameters.py +110 -0
- spectre_core/capture_configs/_pconstraints.py +82 -0
- spectre_core/capture_configs/_ptemplates.py +450 -0
- spectre_core/capture_configs/_pvalidators.py +173 -0
- spectre_core/chunks/__init__.py +17 -201
- spectre_core/chunks/{base.py → _base.py} +15 -60
- spectre_core/chunks/_chunks.py +200 -0
- spectre_core/chunks/{factory.py → _factory.py} +6 -7
- spectre_core/chunks/library/{callisto/chunk.py → _callisto.py} +4 -7
- spectre_core/chunks/library/{fixed/chunk.py → _fixed_center_frequency.py} +7 -64
- spectre_core/chunks/library/_swept_center_frequency.py +103 -0
- spectre_core/config/__init__.py +20 -0
- spectre_core/config/_paths.py +77 -0
- spectre_core/config/_time_formats.py +15 -0
- spectre_core/exceptions.py +4 -5
- spectre_core/logging/__init__.py +11 -0
- spectre_core/logging/_configure.py +35 -0
- spectre_core/logging/_decorators.py +19 -0
- spectre_core/{logging.py → logging/_log_handlers.py} +13 -58
- spectre_core/plotting/__init__.py +7 -1
- spectre_core/plotting/{base.py → _base.py} +40 -20
- spectre_core/plotting/_format.py +18 -0
- spectre_core/plotting/{panel_stack.py → _panel_stack.py} +48 -48
- spectre_core/plotting/_panels.py +234 -0
- spectre_core/post_processing/__init__.py +10 -2
- spectre_core/post_processing/_base.py +119 -0
- spectre_core/post_processing/{factory.py → _factory.py} +7 -6
- spectre_core/post_processing/{post_processor.py → _post_processor.py} +3 -3
- spectre_core/post_processing/library/_fixed_center_frequency.py +115 -0
- spectre_core/post_processing/library/_swept_center_frequency.py +382 -0
- spectre_core/receivers/__init__.py +12 -2
- spectre_core/receivers/_base.py +352 -0
- spectre_core/receivers/{factory.py → _factory.py} +2 -2
- spectre_core/receivers/_spec_names.py +20 -0
- spectre_core/receivers/gr/__init__.py +3 -0
- spectre_core/receivers/gr/_base.py +33 -0
- spectre_core/receivers/gr/_rsp1a.py +158 -0
- spectre_core/receivers/gr/_test.py +123 -0
- spectre_core/receivers/library/_rsp1a.py +61 -0
- spectre_core/receivers/library/_test.py +221 -0
- spectre_core/spectrograms/__init__.py +18 -0
- spectre_core/spectrograms/{analytical.py → _analytical.py} +29 -27
- spectre_core/spectrograms/{array_operations.py → _array_operations.py} +47 -1
- spectre_core/spectrograms/{spectrogram.py → _spectrogram.py} +62 -35
- spectre_core/spectrograms/{transform.py → _transform.py} +76 -89
- spectre_core/{post_processing/library → wgetting}/__init__.py +4 -5
- spectre_core/wgetting/_callisto.py +155 -0
- {spectre_core-0.0.9.dist-info → spectre_core-0.0.10.dist-info}/METADATA +1 -1
- spectre_core-0.0.10.dist-info/RECORD +63 -0
- spectre_core/cfg.py +0 -116
- spectre_core/chunks/library/__init__.py +0 -8
- spectre_core/chunks/library/sweep/__init__.py +0 -0
- spectre_core/chunks/library/sweep/chunk.py +0 -400
- spectre_core/dynamic_imports.py +0 -22
- spectre_core/file_handlers/base.py +0 -68
- spectre_core/file_handlers/configs.py +0 -271
- spectre_core/file_handlers/json.py +0 -40
- spectre_core/file_handlers/text.py +0 -21
- spectre_core/plotting/factory.py +0 -26
- spectre_core/plotting/format.py +0 -19
- spectre_core/plotting/library/__init__.py +0 -7
- spectre_core/plotting/library/frequency_cuts/panel.py +0 -74
- spectre_core/plotting/library/integral_over_frequency/panel.py +0 -34
- spectre_core/plotting/library/spectrogram/panel.py +0 -92
- spectre_core/plotting/library/time_cuts/panel.py +0 -77
- spectre_core/plotting/panel_register.py +0 -13
- spectre_core/post_processing/base.py +0 -132
- spectre_core/post_processing/library/fixed/__init__.py +0 -0
- spectre_core/post_processing/library/fixed/event_handler.py +0 -40
- spectre_core/post_processing/library/sweep/event_handler.py +0 -54
- spectre_core/receivers/base.py +0 -422
- spectre_core/receivers/library/__init__.py +0 -7
- spectre_core/receivers/library/rsp1a/__init__.py +0 -0
- spectre_core/receivers/library/rsp1a/gr/__init__.py +0 -0
- spectre_core/receivers/library/rsp1a/gr/fixed.py +0 -104
- spectre_core/receivers/library/rsp1a/gr/sweep.py +0 -129
- spectre_core/receivers/library/rsp1a/receiver.py +0 -68
- spectre_core/receivers/library/rspduo/__init__.py +0 -0
- spectre_core/receivers/library/rspduo/gr/__init__.py +0 -0
- spectre_core/receivers/library/rspduo/gr/tuner_1_fixed.py +0 -114
- spectre_core/receivers/library/rspduo/gr/tuner_1_sweep.py +0 -131
- spectre_core/receivers/library/rspduo/gr/tuner_2_fixed.py +0 -120
- spectre_core/receivers/library/rspduo/gr/tuner_2_sweep.py +0 -119
- spectre_core/receivers/library/rspduo/receiver.py +0 -97
- spectre_core/receivers/library/test/__init__.py +0 -0
- spectre_core/receivers/library/test/gr/__init__.py +0 -0
- spectre_core/receivers/library/test/gr/cosine_signal_1.py +0 -83
- spectre_core/receivers/library/test/gr/tagged_staircase.py +0 -93
- spectre_core/receivers/library/test/receiver.py +0 -203
- spectre_core/receivers/validators.py +0 -231
- spectre_core/web_fetch/callisto.py +0 -101
- spectre_core-0.0.9.dist-info/RECORD +0 -74
- /spectre_core/chunks/{chunk_register.py → _register.py} +0 -0
- /spectre_core/post_processing/{event_handler_register.py → _register.py} +0 -0
- /spectre_core/receivers/{receiver_register.py → _register.py} +0 -0
- /spectre_core/{chunks/library/callisto/__init__.py → receivers/gr/_rspduo.py} +0 -0
- /spectre_core/{chunks/library/fixed/__init__.py → receivers/library/_rspduo.py} +0 -0
- {spectre_core-0.0.9.dist-info → spectre_core-0.0.10.dist-info}/LICENSE +0 -0
- {spectre_core-0.0.9.dist-info → spectre_core-0.0.10.dist-info}/WHEEL +0 -0
- {spectre_core-0.0.9.dist-info → spectre_core-0.0.10.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,352 @@
|
|
1
|
+
# SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
|
2
|
+
# This file is part of SPECTRE
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
4
|
+
|
5
|
+
from abc import ABC, abstractmethod
|
6
|
+
from typing import Callable, Optional
|
7
|
+
from numbers import Number
|
8
|
+
|
9
|
+
from spectre_core.exceptions import ModeNotFoundError
|
10
|
+
from ._spec_names import SpecNames
|
11
|
+
from spectre_core.capture_configs import (
|
12
|
+
CaptureTemplate, CaptureModes, Parameters, Bound, PValidators, PNames,
|
13
|
+
get_base_capture_template, get_base_ptemplate, OneOf, CaptureConfig
|
14
|
+
)
|
15
|
+
|
16
|
+
class BaseReceiver(ABC):
|
17
|
+
def __init__(self,
|
18
|
+
name: str,
|
19
|
+
mode: Optional[str] = None):
|
20
|
+
self._name = name
|
21
|
+
|
22
|
+
self._specs: dict[str, Number | list[Number]] = {}
|
23
|
+
self._add_specs()
|
24
|
+
|
25
|
+
self._capture_methods: dict[str, Callable] = {}
|
26
|
+
self._add_capture_methods()
|
27
|
+
|
28
|
+
self._pvalidators: dict[str, Callable] = {}
|
29
|
+
self._add_pvalidators()
|
30
|
+
|
31
|
+
self._capture_templates: dict[str, CaptureTemplate] = {}
|
32
|
+
self._add_capture_templates()
|
33
|
+
|
34
|
+
self.mode = mode
|
35
|
+
|
36
|
+
|
37
|
+
@abstractmethod
|
38
|
+
def _add_specs(self) -> None:
|
39
|
+
pass
|
40
|
+
|
41
|
+
|
42
|
+
@abstractmethod
|
43
|
+
def _add_capture_methods(self) -> None:
|
44
|
+
pass
|
45
|
+
|
46
|
+
|
47
|
+
@abstractmethod
|
48
|
+
def _add_pvalidators(self) -> None:
|
49
|
+
pass
|
50
|
+
|
51
|
+
|
52
|
+
@abstractmethod
|
53
|
+
def _add_capture_templates(self) -> None:
|
54
|
+
pass
|
55
|
+
|
56
|
+
|
57
|
+
@property
|
58
|
+
def name(self) -> str:
|
59
|
+
return self._name
|
60
|
+
|
61
|
+
|
62
|
+
@property
|
63
|
+
def capture_methods(self) -> dict[str, Callable]:
|
64
|
+
return self._capture_methods
|
65
|
+
|
66
|
+
|
67
|
+
@property
|
68
|
+
def pvalidators(self) -> dict[str, Callable]:
|
69
|
+
return self._pvalidators
|
70
|
+
|
71
|
+
|
72
|
+
@property
|
73
|
+
def capture_templates(self) -> dict[str, CaptureTemplate]:
|
74
|
+
return self._capture_templates
|
75
|
+
|
76
|
+
|
77
|
+
@property
|
78
|
+
def specs(self) -> dict[str, Number]:
|
79
|
+
return self._specs
|
80
|
+
|
81
|
+
|
82
|
+
@property
|
83
|
+
def modes(self) -> list[str]:
|
84
|
+
capture_method_modes = list(self.capture_methods.keys())
|
85
|
+
pvalidator_modes = list(self.pvalidators.keys())
|
86
|
+
capture_template_modes = list(self.capture_templates.keys())
|
87
|
+
|
88
|
+
if capture_method_modes == pvalidator_modes == capture_template_modes:
|
89
|
+
return capture_method_modes
|
90
|
+
else:
|
91
|
+
raise ValueError(f"Mode mismatch for the receiver {self.name}.")
|
92
|
+
|
93
|
+
|
94
|
+
@property
|
95
|
+
def mode(self) -> str:
|
96
|
+
return self._mode
|
97
|
+
|
98
|
+
|
99
|
+
@mode.setter
|
100
|
+
def mode(self, value: Optional[str]) -> None:
|
101
|
+
if (value is not None) and value not in self.modes:
|
102
|
+
raise ModeNotFoundError((f"{value} is not a defined mode for the receiver {self.name}. "
|
103
|
+
f"Expected one of {self.modes}"))
|
104
|
+
self._mode = value
|
105
|
+
|
106
|
+
|
107
|
+
@property
|
108
|
+
def capture_method(self) -> Callable:
|
109
|
+
return self.capture_methods[self.mode]
|
110
|
+
|
111
|
+
|
112
|
+
@property
|
113
|
+
def pvalidator(self) -> Callable:
|
114
|
+
return self.pvalidators[self.mode]
|
115
|
+
|
116
|
+
|
117
|
+
@property
|
118
|
+
def capture_template(self) -> CaptureTemplate:
|
119
|
+
return self._capture_templates[self.mode]
|
120
|
+
|
121
|
+
|
122
|
+
def add_capture_method(self,
|
123
|
+
mode: str,
|
124
|
+
capture_method: Callable) -> None:
|
125
|
+
self._capture_methods[mode] = capture_method
|
126
|
+
|
127
|
+
|
128
|
+
def add_pvalidator(self,
|
129
|
+
mode: str,
|
130
|
+
pvalidator: Callable) -> None:
|
131
|
+
self._pvalidators[mode] = pvalidator
|
132
|
+
|
133
|
+
|
134
|
+
def add_capture_template(self,
|
135
|
+
mode: str,
|
136
|
+
capture_template: CaptureTemplate) -> CaptureTemplate:
|
137
|
+
self._capture_templates[mode] = capture_template
|
138
|
+
|
139
|
+
|
140
|
+
def add_spec(self,
|
141
|
+
name: str,
|
142
|
+
value: Number) -> None:
|
143
|
+
self.specs[name] = value
|
144
|
+
|
145
|
+
|
146
|
+
def get_spec(self,
|
147
|
+
spec_name: str) -> Number | list[Number]:
|
148
|
+
if spec_name not in self.specs:
|
149
|
+
raise KeyError(f"Spec not found with name '{spec_name}' "
|
150
|
+
f"for the receiver '{self.name}'")
|
151
|
+
return self.specs[spec_name]
|
152
|
+
|
153
|
+
|
154
|
+
def start_capture(self,
|
155
|
+
tag: str) -> None:
|
156
|
+
self.capture_method( tag, self.load_parameters(tag) )
|
157
|
+
|
158
|
+
|
159
|
+
def save_parameters(self,
|
160
|
+
tag: str,
|
161
|
+
parameters: Parameters,
|
162
|
+
force: bool = False) -> None:
|
163
|
+
|
164
|
+
parameters = self.capture_template.apply_template(parameters)
|
165
|
+
self.pvalidator(parameters)
|
166
|
+
|
167
|
+
capture_config = CaptureConfig(tag)
|
168
|
+
capture_config.save_parameters(self.name,
|
169
|
+
self.mode,
|
170
|
+
parameters,
|
171
|
+
force=force)
|
172
|
+
|
173
|
+
def load_parameters(self,
|
174
|
+
tag: str) -> Parameters:
|
175
|
+
capture_config = CaptureConfig(tag)
|
176
|
+
|
177
|
+
parameters = self.capture_template.apply_template(capture_config.parameters)
|
178
|
+
self.pvalidator(parameters)
|
179
|
+
|
180
|
+
return parameters
|
181
|
+
|
182
|
+
|
183
|
+
class SDRPlayReceiver(BaseReceiver):
|
184
|
+
def _get_pvalidator_fixed_center_frequency(self) -> Callable:
|
185
|
+
def pvalidator(parameters: Parameters):
|
186
|
+
PValidators.fixed_center_frequency(parameters)
|
187
|
+
return pvalidator
|
188
|
+
|
189
|
+
|
190
|
+
def _get_pvalidator_swept_center_frequency(self) -> None:
|
191
|
+
def pvalidator(parameters: Parameters):
|
192
|
+
PValidators.swept_center_frequency(parameters,
|
193
|
+
self.get_spec(SpecNames.API_RETUNING_LATENCY))
|
194
|
+
return pvalidator
|
195
|
+
|
196
|
+
|
197
|
+
def _get_capture_template_fixed_center_frequency(self) -> CaptureTemplate:
|
198
|
+
#
|
199
|
+
# Create the base template
|
200
|
+
#
|
201
|
+
capture_template = get_base_capture_template( CaptureModes.FIXED_CENTER_FREQUENCY )
|
202
|
+
capture_template.add_ptemplate( get_base_ptemplate(PNames.BANDWIDTH) )
|
203
|
+
capture_template.add_ptemplate( get_base_ptemplate(PNames.IF_GAIN) )
|
204
|
+
capture_template.add_ptemplate( get_base_ptemplate(PNames.RF_GAIN) )
|
205
|
+
|
206
|
+
#
|
207
|
+
# Update the defaults
|
208
|
+
#
|
209
|
+
capture_template.set_defaults(
|
210
|
+
(PNames.BATCH_SIZE, 3.0),
|
211
|
+
(PNames.CENTER_FREQUENCY, 95800000),
|
212
|
+
(PNames.SAMPLE_RATE, 600000),
|
213
|
+
(PNames.BANDWIDTH, 600000),
|
214
|
+
(PNames.WINDOW_HOP, 512),
|
215
|
+
(PNames.WINDOW_SIZE, 1024),
|
216
|
+
(PNames.WINDOW_TYPE, "blackman"),
|
217
|
+
(PNames.RF_GAIN, -30),
|
218
|
+
(PNames.IF_GAIN, -30)
|
219
|
+
)
|
220
|
+
|
221
|
+
#
|
222
|
+
# Adding pconstraints
|
223
|
+
#
|
224
|
+
capture_template.add_pconstraint(
|
225
|
+
PNames.CENTER_FREQUENCY,
|
226
|
+
[
|
227
|
+
Bound(
|
228
|
+
lower_bound=self.get_spec(SpecNames.FREQUENCY_LOWER_BOUND),
|
229
|
+
upper_bound=self.get_spec(SpecNames.FREQUENCY_UPPER_BOUND)
|
230
|
+
)
|
231
|
+
]
|
232
|
+
)
|
233
|
+
capture_template.add_pconstraint(
|
234
|
+
PNames.SAMPLE_RATE,
|
235
|
+
[
|
236
|
+
Bound(
|
237
|
+
lower_bound=self.get_spec(SpecNames.SAMPLE_RATE_LOWER_BOUND),
|
238
|
+
upper_bound=self.get_spec(SpecNames.SAMPLE_RATE_UPPER_BOUND)
|
239
|
+
)
|
240
|
+
]
|
241
|
+
)
|
242
|
+
capture_template.add_pconstraint(
|
243
|
+
PNames.BANDWIDTH,
|
244
|
+
[
|
245
|
+
OneOf(
|
246
|
+
self.get_spec( SpecNames.BANDWIDTH_OPTIONS )
|
247
|
+
)
|
248
|
+
]
|
249
|
+
)
|
250
|
+
capture_template.add_pconstraint(
|
251
|
+
PNames.IF_GAIN,
|
252
|
+
[
|
253
|
+
Bound(
|
254
|
+
upper_bound=self.get_spec(SpecNames.IF_GAIN_UPPER_BOUND)
|
255
|
+
)
|
256
|
+
]
|
257
|
+
)
|
258
|
+
capture_template.add_pconstraint(
|
259
|
+
PNames.RF_GAIN,
|
260
|
+
[
|
261
|
+
Bound(
|
262
|
+
upper_bound=self.get_spec(SpecNames.RF_GAIN_UPPER_BOUND)
|
263
|
+
)
|
264
|
+
]
|
265
|
+
)
|
266
|
+
return capture_template
|
267
|
+
|
268
|
+
|
269
|
+
def _get_capture_template_swept_center_frequency(self) -> CaptureTemplate:
|
270
|
+
#
|
271
|
+
# Create the base template
|
272
|
+
#
|
273
|
+
capture_template = get_base_capture_template( CaptureModes.SWEPT_CENTER_FREQUENCY )
|
274
|
+
capture_template.add_ptemplate( get_base_ptemplate(PNames.BANDWIDTH) )
|
275
|
+
capture_template.add_ptemplate( get_base_ptemplate(PNames.IF_GAIN) )
|
276
|
+
capture_template.add_ptemplate( get_base_ptemplate(PNames.RF_GAIN) )
|
277
|
+
|
278
|
+
|
279
|
+
#
|
280
|
+
# Update the defaults
|
281
|
+
#
|
282
|
+
capture_template.set_defaults(
|
283
|
+
(PNames.BATCH_SIZE, 3.0),
|
284
|
+
(PNames.MIN_FREQUENCY, 90000000),
|
285
|
+
(PNames.MAX_FREQUENCY, 110000000),
|
286
|
+
(PNames.SAMPLES_PER_STEP, 300000),
|
287
|
+
(PNames.FREQUENCY_STEP, 1536000),
|
288
|
+
(PNames.SAMPLE_RATE, 1536000),
|
289
|
+
(PNames.BANDWIDTH, 1536000),
|
290
|
+
(PNames.WINDOW_HOP, 512),
|
291
|
+
(PNames.WINDOW_SIZE, 1024),
|
292
|
+
(PNames.WINDOW_TYPE, "blackman"),
|
293
|
+
(PNames.RF_GAIN, -30),
|
294
|
+
(PNames.IF_GAIN, -30)
|
295
|
+
)
|
296
|
+
|
297
|
+
|
298
|
+
#
|
299
|
+
# Adding pconstraints
|
300
|
+
#
|
301
|
+
capture_template.add_pconstraint(
|
302
|
+
PNames.MIN_FREQUENCY,
|
303
|
+
[
|
304
|
+
Bound(
|
305
|
+
lower_bound=self.get_spec(SpecNames.FREQUENCY_LOWER_BOUND),
|
306
|
+
upper_bound=self.get_spec(SpecNames.FREQUENCY_UPPER_BOUND)
|
307
|
+
)
|
308
|
+
]
|
309
|
+
)
|
310
|
+
capture_template.add_pconstraint(
|
311
|
+
PNames.MAX_FREQUENCY,
|
312
|
+
[
|
313
|
+
Bound(
|
314
|
+
lower_bound=self.get_spec(SpecNames.FREQUENCY_LOWER_BOUND),
|
315
|
+
upper_bound=self.get_spec(SpecNames.FREQUENCY_UPPER_BOUND)
|
316
|
+
)
|
317
|
+
]
|
318
|
+
)
|
319
|
+
capture_template.add_pconstraint(
|
320
|
+
PNames.SAMPLE_RATE,
|
321
|
+
[
|
322
|
+
Bound(
|
323
|
+
lower_bound=self.get_spec(SpecNames.SAMPLE_RATE_LOWER_BOUND),
|
324
|
+
upper_bound=self.get_spec(SpecNames.SAMPLE_RATE_UPPER_BOUND)
|
325
|
+
)
|
326
|
+
]
|
327
|
+
)
|
328
|
+
capture_template.add_pconstraint(
|
329
|
+
PNames.BANDWIDTH,
|
330
|
+
[
|
331
|
+
OneOf(
|
332
|
+
self.get_spec( SpecNames.BANDWIDTH_OPTIONS )
|
333
|
+
)
|
334
|
+
]
|
335
|
+
)
|
336
|
+
capture_template.add_pconstraint(
|
337
|
+
PNames.IF_GAIN,
|
338
|
+
[
|
339
|
+
Bound(
|
340
|
+
upper_bound=self.get_spec(SpecNames.IF_GAIN_UPPER_BOUND)
|
341
|
+
)
|
342
|
+
]
|
343
|
+
)
|
344
|
+
capture_template.add_pconstraint(
|
345
|
+
PNames.RF_GAIN,
|
346
|
+
[
|
347
|
+
Bound(
|
348
|
+
upper_bound=self.get_spec(SpecNames.RF_GAIN_UPPER_BOUND)
|
349
|
+
)
|
350
|
+
]
|
351
|
+
)
|
352
|
+
return capture_template
|
@@ -4,9 +4,9 @@
|
|
4
4
|
|
5
5
|
from typing import Optional
|
6
6
|
|
7
|
-
from spectre_core.receivers.receiver_register import receivers
|
8
|
-
from spectre_core.receivers.base import BaseReceiver
|
9
7
|
from spectre_core.exceptions import ReceiverNotFoundError
|
8
|
+
from ._register import receivers
|
9
|
+
from ._base import BaseReceiver
|
10
10
|
|
11
11
|
# used to fetch an instance of the receiver class
|
12
12
|
def get_receiver(receiver_name: str, mode: Optional[str] = None) -> BaseReceiver:
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
|
2
|
+
# This file is part of SPECTRE
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
4
|
+
|
5
|
+
from dataclasses import dataclass
|
6
|
+
|
7
|
+
@dataclass(frozen=True)
|
8
|
+
class SpecNames:
|
9
|
+
"""A centralised store of specification names"""
|
10
|
+
FREQUENCY_LOWER_BOUND : str = "frequency_lower_bound"
|
11
|
+
FREQUENCY_UPPER_BOUND : str = "frequency_upper_bound"
|
12
|
+
SAMPLE_RATE_LOWER_BOUND : str = "sample_rate_lower_bound"
|
13
|
+
SAMPLE_RATE_UPPER_BOUND : str = "sample_rate_upper_bound"
|
14
|
+
BANDWIDTH_LOWER_BOUND : str = "bandwidth_lower_bound"
|
15
|
+
BANDWIDTH_UPPER_BOUND : str = "bandwidth_upper_bound"
|
16
|
+
BANDWIDTH_OPTIONS : str = "bandwidth_options"
|
17
|
+
DEFINED_BANDWIDTHS : str = "defined_bandwidths"
|
18
|
+
IF_GAIN_UPPER_BOUND : str = "if_gain_upper_bound"
|
19
|
+
RF_GAIN_UPPER_BOUND : str = "rf_gain_upper_bound"
|
20
|
+
API_RETUNING_LATENCY : str = "api_retuning_latency"
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
|
2
|
+
# This file is part of SPECTRE
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
4
|
+
|
5
|
+
import sys
|
6
|
+
import signal
|
7
|
+
|
8
|
+
from gnuradio import gr
|
9
|
+
from gnuradio import spectre
|
10
|
+
|
11
|
+
from spectre_core.capture_configs import Parameters, PNames
|
12
|
+
from spectre_core.config import get_chunks_dir_path
|
13
|
+
|
14
|
+
from spectre_core.capture_configs import Parameters
|
15
|
+
|
16
|
+
|
17
|
+
def capture(tag: str,
|
18
|
+
parameters: Parameters,
|
19
|
+
top_block_cls: gr.top_block,
|
20
|
+
max_noutput_items: int = 10000000):
|
21
|
+
tb: gr.top_block = top_block_cls(tag,
|
22
|
+
parameters)
|
23
|
+
|
24
|
+
def sig_handler(sig=None, frame=None):
|
25
|
+
tb.stop()
|
26
|
+
tb.wait()
|
27
|
+
sys.exit(0)
|
28
|
+
|
29
|
+
signal.signal(signal.SIGINT, sig_handler)
|
30
|
+
signal.signal(signal.SIGTERM, sig_handler)
|
31
|
+
|
32
|
+
tb.start(max_noutput_items)
|
33
|
+
tb.wait()
|
@@ -0,0 +1,158 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: GPL-3.0
|
6
|
+
#
|
7
|
+
# GNU Radio Python Flow Graph
|
8
|
+
# Title: Test receiver
|
9
|
+
# GNU Radio version: 3.10.1.1
|
10
|
+
|
11
|
+
# SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
|
12
|
+
# This file is part of SPECTRE
|
13
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
14
|
+
|
15
|
+
#
|
16
|
+
# Test receiver top blocks
|
17
|
+
#
|
18
|
+
|
19
|
+
from functools import partial
|
20
|
+
from dataclasses import dataclass
|
21
|
+
|
22
|
+
from gnuradio import gr
|
23
|
+
from gnuradio import spectre
|
24
|
+
from gnuradio import sdrplay3
|
25
|
+
|
26
|
+
from spectre_core.capture_configs import Parameters, PNames
|
27
|
+
from spectre_core.config import get_chunks_dir_path
|
28
|
+
from ._base import capture
|
29
|
+
|
30
|
+
class _fixed_center_frequency(gr.top_block):
|
31
|
+
def __init__(self,
|
32
|
+
tag: str,
|
33
|
+
parameters: Parameters):
|
34
|
+
gr.top_block.__init__(self, "fixed-center-frequency", catch_exceptions=True)
|
35
|
+
|
36
|
+
##################################################
|
37
|
+
# Unpack capture config
|
38
|
+
##################################################
|
39
|
+
sample_rate = parameters.get_parameter_value(PNames.SAMPLE_RATE)
|
40
|
+
batch_size = parameters.get_parameter_value(PNames.BATCH_SIZE)
|
41
|
+
center_freq = parameters.get_parameter_value(PNames.CENTER_FREQUENCY)
|
42
|
+
bandwidth = parameters.get_parameter_value(PNames.BANDWIDTH)
|
43
|
+
if_gain = parameters.get_parameter_value(PNames.IF_GAIN)
|
44
|
+
rf_gain = parameters.get_parameter_value(PNames.RF_GAIN)
|
45
|
+
is_sweeping = False
|
46
|
+
|
47
|
+
##################################################
|
48
|
+
# Blocks
|
49
|
+
##################################################
|
50
|
+
self.spectre_batched_file_sink_0 = spectre.batched_file_sink(get_chunks_dir_path(),
|
51
|
+
tag,
|
52
|
+
batch_size,
|
53
|
+
sample_rate)
|
54
|
+
self.sdrplay3_rsp1a_0 = sdrplay3.rsp1a(
|
55
|
+
'',
|
56
|
+
stream_args=sdrplay3.stream_args(
|
57
|
+
output_type='fc32',
|
58
|
+
channels_size=1
|
59
|
+
),
|
60
|
+
)
|
61
|
+
self.sdrplay3_rsp1a_0.set_sample_rate(sample_rate)
|
62
|
+
self.sdrplay3_rsp1a_0.set_center_freq(center_freq)
|
63
|
+
self.sdrplay3_rsp1a_0.set_bandwidth(bandwidth)
|
64
|
+
self.sdrplay3_rsp1a_0.set_gain_mode(False)
|
65
|
+
self.sdrplay3_rsp1a_0.set_gain(if_gain, 'IF')
|
66
|
+
self.sdrplay3_rsp1a_0.set_gain(rf_gain, 'RF')
|
67
|
+
self.sdrplay3_rsp1a_0.set_freq_corr(0)
|
68
|
+
self.sdrplay3_rsp1a_0.set_dc_offset_mode(False)
|
69
|
+
self.sdrplay3_rsp1a_0.set_iq_balance_mode(False)
|
70
|
+
self.sdrplay3_rsp1a_0.set_agc_setpoint(-30)
|
71
|
+
self.sdrplay3_rsp1a_0.set_rf_notch_filter(False)
|
72
|
+
self.sdrplay3_rsp1a_0.set_dab_notch_filter(False)
|
73
|
+
self.sdrplay3_rsp1a_0.set_biasT(False)
|
74
|
+
self.sdrplay3_rsp1a_0.set_debug_mode(False)
|
75
|
+
self.sdrplay3_rsp1a_0.set_sample_sequence_gaps_check(False)
|
76
|
+
self.sdrplay3_rsp1a_0.set_show_gain_changes(False)
|
77
|
+
|
78
|
+
|
79
|
+
##################################################
|
80
|
+
# Connections
|
81
|
+
##################################################
|
82
|
+
self.connect((self.sdrplay3_rsp1a_0, 0), (self.spectre_batched_file_sink_0, 0))
|
83
|
+
|
84
|
+
|
85
|
+
class _swept_center_frequency(gr.top_block):
|
86
|
+
def __init__(self,
|
87
|
+
tag: str,
|
88
|
+
parameters: Parameters):
|
89
|
+
gr.top_block.__init__(self, "sweep", catch_exceptions=True)
|
90
|
+
|
91
|
+
##################################################
|
92
|
+
# Unpack capture config
|
93
|
+
##################################################
|
94
|
+
sample_rate = parameters.get_parameter_value(PNames.SAMPLE_RATE)
|
95
|
+
bandwidth = parameters.get_parameter_value(PNames.BANDWIDTH)
|
96
|
+
min_frequency = parameters.get_parameter_value(PNames.MIN_FREQUENCY)
|
97
|
+
max_frequency = parameters.get_parameter_value(PNames.MAX_FREQUENCY)
|
98
|
+
frequency_step = parameters.get_parameter_value(PNames.FREQUENCY_STEP)
|
99
|
+
samples_per_step = parameters.get_parameter_value(PNames.SAMPLES_PER_STEP)
|
100
|
+
if_gain = parameters.get_parameter_value(PNames.IF_GAIN)
|
101
|
+
rf_gain = parameters.get_parameter_value(PNames.RF_GAIN)
|
102
|
+
batch_size = parameters.get_parameter_value(PNames.BATCH_SIZE)
|
103
|
+
|
104
|
+
|
105
|
+
##################################################
|
106
|
+
# Blocks
|
107
|
+
##################################################
|
108
|
+
self.spectre_sweep_driver_0 = spectre.sweep_driver(min_frequency,
|
109
|
+
max_frequency,
|
110
|
+
frequency_step,
|
111
|
+
sample_rate,
|
112
|
+
samples_per_step,
|
113
|
+
'freq')
|
114
|
+
self.spectre_batched_file_sink_0 = spectre.batched_file_sink(get_chunks_dir_path(),
|
115
|
+
tag,
|
116
|
+
batch_size,
|
117
|
+
sample_rate,
|
118
|
+
True,
|
119
|
+
'freq',
|
120
|
+
min_frequency)
|
121
|
+
self.sdrplay3_rsp1a_0 = sdrplay3.rsp1a(
|
122
|
+
'',
|
123
|
+
stream_args=sdrplay3.stream_args(
|
124
|
+
output_type='fc32',
|
125
|
+
channels_size=1
|
126
|
+
),
|
127
|
+
)
|
128
|
+
self.sdrplay3_rsp1a_0.set_sample_rate(sample_rate, True)
|
129
|
+
self.sdrplay3_rsp1a_0.set_center_freq(min_frequency, True)
|
130
|
+
self.sdrplay3_rsp1a_0.set_bandwidth(bandwidth)
|
131
|
+
self.sdrplay3_rsp1a_0.set_gain_mode(False)
|
132
|
+
self.sdrplay3_rsp1a_0.set_gain(if_gain, 'IF', True)
|
133
|
+
self.sdrplay3_rsp1a_0.set_gain(rf_gain, 'RF', True)
|
134
|
+
self.sdrplay3_rsp1a_0.set_freq_corr(0)
|
135
|
+
self.sdrplay3_rsp1a_0.set_dc_offset_mode(False)
|
136
|
+
self.sdrplay3_rsp1a_0.set_iq_balance_mode(False)
|
137
|
+
self.sdrplay3_rsp1a_0.set_agc_setpoint(-30)
|
138
|
+
self.sdrplay3_rsp1a_0.set_rf_notch_filter(False)
|
139
|
+
self.sdrplay3_rsp1a_0.set_dab_notch_filter(False)
|
140
|
+
self.sdrplay3_rsp1a_0.set_biasT(False)
|
141
|
+
self.sdrplay3_rsp1a_0.set_stream_tags(True)
|
142
|
+
self.sdrplay3_rsp1a_0.set_debug_mode(False)
|
143
|
+
self.sdrplay3_rsp1a_0.set_sample_sequence_gaps_check(False)
|
144
|
+
self.sdrplay3_rsp1a_0.set_show_gain_changes(False)
|
145
|
+
|
146
|
+
|
147
|
+
##################################################
|
148
|
+
# Connections
|
149
|
+
##################################################
|
150
|
+
self.msg_connect((self.spectre_sweep_driver_0, 'freq'), (self.sdrplay3_rsp1a_0, 'freq'))
|
151
|
+
self.connect((self.sdrplay3_rsp1a_0, 0), (self.spectre_batched_file_sink_0, 0))
|
152
|
+
self.connect((self.sdrplay3_rsp1a_0, 0), (self.spectre_sweep_driver_0, 0))
|
153
|
+
|
154
|
+
|
155
|
+
@dataclass(frozen=True)
|
156
|
+
class CaptureMethods:
|
157
|
+
fixed_center_frequency = partial(capture, top_block_cls=_fixed_center_frequency)
|
158
|
+
_swept_center_frequency = partial(capture, top_block_cls=_swept_center_frequency)
|