spectre-core 0.0.21__py3-none-any.whl → 0.0.23__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/_file_io/__init__.py +5 -5
- spectre_core/_file_io/file_handlers.py +61 -107
- spectre_core/batches/__init__.py +21 -4
- spectre_core/batches/_base.py +86 -135
- spectre_core/batches/_batches.py +56 -100
- spectre_core/batches/_factory.py +22 -21
- spectre_core/batches/_register.py +9 -9
- spectre_core/batches/plugins/_batch_keys.py +8 -7
- spectre_core/batches/plugins/_callisto.py +66 -98
- spectre_core/batches/plugins/_iq_stream.py +106 -170
- spectre_core/capture_configs/__init__.py +47 -18
- spectre_core/capture_configs/_capture_config.py +26 -53
- spectre_core/capture_configs/_capture_modes.py +9 -7
- spectre_core/capture_configs/_capture_templates.py +51 -111
- spectre_core/capture_configs/_parameters.py +38 -75
- spectre_core/capture_configs/_pconstraints.py +41 -41
- spectre_core/capture_configs/_pnames.py +37 -35
- spectre_core/capture_configs/_ptemplates.py +261 -348
- spectre_core/capture_configs/_pvalidators.py +99 -102
- spectre_core/config/__init__.py +14 -9
- spectre_core/config/_paths.py +19 -36
- spectre_core/config/_time_formats.py +7 -6
- spectre_core/exceptions.py +39 -1
- spectre_core/jobs/__init__.py +4 -7
- spectre_core/jobs/_duration.py +12 -0
- spectre_core/jobs/_jobs.py +73 -44
- spectre_core/jobs/_workers.py +56 -106
- spectre_core/logs/__init__.py +8 -3
- spectre_core/logs/_configure.py +14 -18
- spectre_core/logs/_decorators.py +7 -5
- spectre_core/logs/_logs.py +38 -90
- spectre_core/logs/_process_types.py +6 -4
- spectre_core/plotting/__init__.py +14 -4
- spectre_core/plotting/_base.py +65 -139
- spectre_core/plotting/_format.py +11 -9
- spectre_core/plotting/_panel_names.py +8 -6
- spectre_core/plotting/_panel_stack.py +83 -116
- spectre_core/plotting/_panels.py +121 -156
- spectre_core/post_processing/__init__.py +7 -4
- spectre_core/post_processing/_base.py +69 -69
- spectre_core/post_processing/_factory.py +15 -12
- spectre_core/post_processing/_post_processor.py +17 -13
- spectre_core/post_processing/_register.py +11 -8
- spectre_core/post_processing/plugins/_event_handler_keys.py +5 -4
- spectre_core/post_processing/plugins/_fixed_center_frequency.py +55 -48
- spectre_core/post_processing/plugins/_swept_center_frequency.py +200 -175
- spectre_core/receivers/__init__.py +10 -3
- spectre_core/receivers/_base.py +83 -149
- spectre_core/receivers/_factory.py +21 -31
- spectre_core/receivers/_register.py +8 -11
- spectre_core/receivers/_spec_names.py +18 -16
- spectre_core/receivers/plugins/_b200mini.py +48 -61
- spectre_core/receivers/plugins/_receiver_names.py +9 -7
- spectre_core/receivers/plugins/_rsp1a.py +45 -41
- spectre_core/receivers/plugins/_rspduo.py +60 -45
- spectre_core/receivers/plugins/_sdrplay_receiver.py +68 -84
- spectre_core/receivers/plugins/_test.py +137 -130
- spectre_core/receivers/plugins/_usrp.py +94 -86
- spectre_core/receivers/plugins/gr/__init__.py +2 -2
- spectre_core/receivers/plugins/gr/_base.py +15 -23
- spectre_core/receivers/plugins/gr/_rsp1a.py +53 -60
- spectre_core/receivers/plugins/gr/_rspduo.py +78 -90
- spectre_core/receivers/plugins/gr/_test.py +50 -58
- spectre_core/receivers/plugins/gr/_usrp.py +61 -59
- spectre_core/spectrograms/__init__.py +22 -14
- spectre_core/spectrograms/_analytical.py +109 -100
- spectre_core/spectrograms/_array_operations.py +40 -47
- spectre_core/spectrograms/_spectrogram.py +290 -323
- spectre_core/spectrograms/_transform.py +107 -74
- spectre_core/wgetting/__init__.py +2 -4
- spectre_core/wgetting/_callisto.py +88 -94
- {spectre_core-0.0.21.dist-info → spectre_core-0.0.23.dist-info}/METADATA +9 -23
- spectre_core-0.0.23.dist-info/RECORD +79 -0
- {spectre_core-0.0.21.dist-info → spectre_core-0.0.23.dist-info}/WHEEL +1 -1
- spectre_core-0.0.21.dist-info/RECORD +0 -78
- {spectre_core-0.0.21.dist-info → spectre_core-0.0.23.dist-info}/licenses/LICENSE +0 -0
- {spectre_core-0.0.21.dist-info → spectre_core-0.0.23.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
# SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
|
1
|
+
# SPDX-FileCopyrightText: © 2024-2025 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
|
2
2
|
# This file is part of SPECTRE
|
3
3
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
4
4
|
|
@@ -6,9 +6,15 @@ from dataclasses import dataclass
|
|
6
6
|
from typing import Callable, cast
|
7
7
|
|
8
8
|
from spectre_core.capture_configs import (
|
9
|
-
CaptureTemplate,
|
10
|
-
|
11
|
-
|
9
|
+
CaptureTemplate,
|
10
|
+
CaptureMode,
|
11
|
+
Parameters,
|
12
|
+
Bound,
|
13
|
+
PName,
|
14
|
+
get_base_capture_template,
|
15
|
+
make_base_capture_template,
|
16
|
+
get_base_ptemplate,
|
17
|
+
validate_window,
|
12
18
|
)
|
13
19
|
from .gr._test import CaptureMethod
|
14
20
|
from ._receiver_names import ReceiverName
|
@@ -20,137 +26,123 @@ from .._register import register_receiver
|
|
20
26
|
@dataclass(frozen=True)
|
21
27
|
class Mode:
|
22
28
|
"""An operating mode for the `Test` receiver."""
|
23
|
-
|
29
|
+
|
30
|
+
COSINE_SIGNAL_1 = "cosine_signal_1"
|
24
31
|
TAGGED_STAIRCASE = "tagged_staircase"
|
25
32
|
|
26
33
|
|
27
34
|
@register_receiver(ReceiverName.TEST)
|
28
35
|
class Test(BaseReceiver):
|
29
36
|
"""An entirely software-defined receiver, which generates synthetic signals."""
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
self.add_spec(
|
34
|
-
self.add_spec(
|
35
|
-
self.add_spec(
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
) -> None:
|
42
|
-
self.
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
self.
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
def
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
self.__get_capture_template_cosine_signal_1() )
|
62
|
-
self.add_capture_template(Mode.TAGGED_STAIRCASE,
|
63
|
-
self.__get_capture_template_tagged_staircase() )
|
64
|
-
|
65
|
-
|
66
|
-
def __get_capture_template_cosine_signal_1(
|
67
|
-
self
|
68
|
-
) -> CaptureTemplate:
|
69
|
-
capture_template = get_base_capture_template( CaptureMode.FIXED_CENTER_FREQUENCY )
|
70
|
-
capture_template.add_ptemplate( get_base_ptemplate(PName.AMPLITUDE) )
|
71
|
-
capture_template.add_ptemplate( get_base_ptemplate(PName.FREQUENCY) )
|
37
|
+
|
38
|
+
def _add_specs(self) -> None:
|
39
|
+
self.add_spec(SpecName.SAMPLE_RATE_LOWER_BOUND, 64000)
|
40
|
+
self.add_spec(SpecName.SAMPLE_RATE_UPPER_BOUND, 640000)
|
41
|
+
self.add_spec(SpecName.FREQUENCY_LOWER_BOUND, 16000)
|
42
|
+
self.add_spec(SpecName.FREQUENCY_UPPER_BOUND, 160000)
|
43
|
+
|
44
|
+
def _add_capture_methods(self) -> None:
|
45
|
+
self.add_capture_method(Mode.COSINE_SIGNAL_1, CaptureMethod.cosine_signal_1)
|
46
|
+
self.add_capture_method(Mode.TAGGED_STAIRCASE, CaptureMethod.tagged_staircase)
|
47
|
+
|
48
|
+
def _add_pvalidators(self) -> None:
|
49
|
+
self.add_pvalidator(
|
50
|
+
Mode.COSINE_SIGNAL_1, self.__get_pvalidator_cosine_signal_1()
|
51
|
+
)
|
52
|
+
self.add_pvalidator(
|
53
|
+
Mode.TAGGED_STAIRCASE, self.__get_pvalidator_tagged_staircase()
|
54
|
+
)
|
55
|
+
|
56
|
+
def _add_capture_templates(self) -> None:
|
57
|
+
self.add_capture_template(
|
58
|
+
Mode.COSINE_SIGNAL_1, self.__get_capture_template_cosine_signal_1()
|
59
|
+
)
|
60
|
+
self.add_capture_template(
|
61
|
+
Mode.TAGGED_STAIRCASE, self.__get_capture_template_tagged_staircase()
|
62
|
+
)
|
63
|
+
|
64
|
+
def __get_capture_template_cosine_signal_1(self) -> CaptureTemplate:
|
65
|
+
capture_template = get_base_capture_template(CaptureMode.FIXED_CENTER_FREQUENCY)
|
66
|
+
capture_template.add_ptemplate(get_base_ptemplate(PName.AMPLITUDE))
|
67
|
+
capture_template.add_ptemplate(get_base_ptemplate(PName.FREQUENCY))
|
72
68
|
|
73
69
|
capture_template.set_defaults(
|
74
|
-
(PName.BATCH_SIZE,
|
75
|
-
(PName.CENTER_FREQUENCY,
|
76
|
-
(PName.AMPLITUDE,
|
77
|
-
(PName.FREQUENCY,
|
78
|
-
(PName.SAMPLE_RATE,
|
79
|
-
(PName.WINDOW_HOP,
|
80
|
-
(PName.WINDOW_SIZE,
|
81
|
-
(PName.WINDOW_TYPE,
|
70
|
+
(PName.BATCH_SIZE, 3.0),
|
71
|
+
(PName.CENTER_FREQUENCY, 16000),
|
72
|
+
(PName.AMPLITUDE, 2.0),
|
73
|
+
(PName.FREQUENCY, 32000),
|
74
|
+
(PName.SAMPLE_RATE, 128000),
|
75
|
+
(PName.WINDOW_HOP, 512),
|
76
|
+
(PName.WINDOW_SIZE, 512),
|
77
|
+
(PName.WINDOW_TYPE, "boxcar"),
|
82
78
|
)
|
83
79
|
|
84
80
|
capture_template.enforce_defaults(
|
85
81
|
PName.TIME_RESOLUTION,
|
86
82
|
PName.TIME_RANGE,
|
87
83
|
PName.FREQUENCY_RESOLUTION,
|
88
|
-
PName.WINDOW_TYPE
|
84
|
+
PName.WINDOW_TYPE,
|
89
85
|
)
|
90
86
|
|
91
|
-
|
92
87
|
capture_template.add_pconstraint(
|
93
88
|
PName.SAMPLE_RATE,
|
94
89
|
[
|
95
90
|
Bound(
|
96
91
|
lower_bound=self.get_spec(SpecName.SAMPLE_RATE_LOWER_BOUND),
|
97
|
-
upper_bound=self.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND)
|
92
|
+
upper_bound=self.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND),
|
98
93
|
)
|
99
|
-
]
|
94
|
+
],
|
100
95
|
)
|
101
96
|
capture_template.add_pconstraint(
|
102
97
|
PName.FREQUENCY,
|
103
98
|
[
|
104
99
|
Bound(
|
105
100
|
lower_bound=self.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
|
106
|
-
upper_bound=self.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
|
101
|
+
upper_bound=self.get_spec(SpecName.FREQUENCY_UPPER_BOUND),
|
107
102
|
)
|
108
|
-
]
|
103
|
+
],
|
109
104
|
)
|
110
105
|
return capture_template
|
111
106
|
|
112
|
-
|
113
|
-
def __get_capture_template_tagged_staircase(
|
114
|
-
self
|
115
|
-
) -> CaptureTemplate:
|
107
|
+
def __get_capture_template_tagged_staircase(self) -> CaptureTemplate:
|
116
108
|
capture_template = make_base_capture_template(
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
109
|
+
PName.TIME_RESOLUTION,
|
110
|
+
PName.FREQUENCY_RESOLUTION,
|
111
|
+
PName.TIME_RANGE,
|
112
|
+
PName.SAMPLE_RATE,
|
113
|
+
PName.BATCH_SIZE,
|
114
|
+
PName.WINDOW_TYPE,
|
115
|
+
PName.WINDOW_HOP,
|
116
|
+
PName.WINDOW_SIZE,
|
117
|
+
PName.EVENT_HANDLER_KEY,
|
118
|
+
PName.BATCH_KEY,
|
119
|
+
PName.WATCH_EXTENSION,
|
120
|
+
PName.MIN_SAMPLES_PER_STEP,
|
121
|
+
PName.MAX_SAMPLES_PER_STEP,
|
122
|
+
PName.FREQUENCY_STEP,
|
123
|
+
PName.STEP_INCREMENT,
|
124
|
+
PName.OBS_ALT,
|
125
|
+
PName.OBS_LAT,
|
126
|
+
PName.OBS_LON,
|
127
|
+
PName.OBJECT,
|
128
|
+
PName.ORIGIN,
|
129
|
+
PName.TELESCOPE,
|
130
|
+
PName.INSTRUMENT,
|
139
131
|
)
|
140
132
|
|
141
133
|
capture_template.set_defaults(
|
142
|
-
(PName.BATCH_SIZE,
|
143
|
-
(PName.FREQUENCY_STEP,
|
144
|
-
(PName.MAX_SAMPLES_PER_STEP,
|
145
|
-
(PName.MIN_SAMPLES_PER_STEP,
|
146
|
-
(PName.SAMPLE_RATE,
|
147
|
-
(PName.STEP_INCREMENT,
|
148
|
-
(PName.WINDOW_HOP,
|
149
|
-
(PName.WINDOW_SIZE,
|
150
|
-
(PName.WINDOW_TYPE,
|
151
|
-
(PName.EVENT_HANDLER_KEY,
|
152
|
-
(PName.BATCH_KEY,
|
153
|
-
(PName.WATCH_EXTENSION,
|
134
|
+
(PName.BATCH_SIZE, 3.0),
|
135
|
+
(PName.FREQUENCY_STEP, 128000),
|
136
|
+
(PName.MAX_SAMPLES_PER_STEP, 5000),
|
137
|
+
(PName.MIN_SAMPLES_PER_STEP, 4000),
|
138
|
+
(PName.SAMPLE_RATE, 128000),
|
139
|
+
(PName.STEP_INCREMENT, 200),
|
140
|
+
(PName.WINDOW_HOP, 512),
|
141
|
+
(PName.WINDOW_SIZE, 512),
|
142
|
+
(PName.WINDOW_TYPE, "boxcar"),
|
143
|
+
(PName.EVENT_HANDLER_KEY, "swept_center_frequency"),
|
144
|
+
(PName.BATCH_KEY, "iq_stream"),
|
145
|
+
(PName.WATCH_EXTENSION, "bin"),
|
154
146
|
)
|
155
147
|
|
156
148
|
capture_template.enforce_defaults(
|
@@ -160,59 +152,74 @@ class Test(BaseReceiver):
|
|
160
152
|
PName.WINDOW_TYPE,
|
161
153
|
PName.EVENT_HANDLER_KEY,
|
162
154
|
PName.BATCH_KEY,
|
163
|
-
PName.WATCH_EXTENSION
|
155
|
+
PName.WATCH_EXTENSION,
|
164
156
|
)
|
165
157
|
|
166
158
|
return capture_template
|
167
|
-
|
168
|
-
|
169
|
-
def __get_pvalidator_cosine_signal_1(
|
170
|
-
self
|
171
|
-
) -> Callable[[Parameters], None]:
|
159
|
+
|
160
|
+
def __get_pvalidator_cosine_signal_1(self) -> Callable[[Parameters], None]:
|
172
161
|
def pvalidator(parameters: Parameters) -> None:
|
173
162
|
validate_window(parameters)
|
174
163
|
|
175
|
-
sample_rate
|
176
|
-
window_size
|
177
|
-
frequency
|
164
|
+
sample_rate = cast(int, parameters.get_parameter_value(PName.SAMPLE_RATE))
|
165
|
+
window_size = cast(int, parameters.get_parameter_value(PName.WINDOW_SIZE))
|
166
|
+
frequency = cast(float, parameters.get_parameter_value(PName.FREQUENCY))
|
178
167
|
|
179
168
|
# check that the sample rate is an integer multiple of the underlying signal frequency
|
180
169
|
if sample_rate % frequency != 0:
|
181
|
-
raise ValueError(
|
170
|
+
raise ValueError(
|
171
|
+
"The sampling rate must be some integer multiple of frequency"
|
172
|
+
)
|
182
173
|
|
183
|
-
a = sample_rate/frequency
|
174
|
+
a = sample_rate / frequency
|
184
175
|
if a < 2:
|
185
|
-
raise ValueError(
|
186
|
-
|
187
|
-
|
176
|
+
raise ValueError(
|
177
|
+
(
|
178
|
+
f"The ratio of sampling rate over frequency must be greater than two. "
|
179
|
+
f"Got {a}"
|
180
|
+
)
|
181
|
+
)
|
182
|
+
|
188
183
|
# analytical requirement
|
189
184
|
# if p is the number of sampled cycles, we can find that p = window_size / a
|
190
185
|
# the number of sampled cycles must be a positive natural number.
|
191
186
|
p = window_size / a
|
192
187
|
if window_size % a != 0:
|
193
|
-
raise ValueError(
|
194
|
-
|
195
|
-
|
188
|
+
raise ValueError(
|
189
|
+
(
|
190
|
+
f"The number of sampled cycles must be a positive natural number. "
|
191
|
+
f"Computed that p={p}"
|
192
|
+
)
|
193
|
+
)
|
196
194
|
|
195
|
+
return pvalidator
|
197
196
|
|
198
|
-
def __get_pvalidator_tagged_staircase(
|
199
|
-
self
|
200
|
-
) -> Callable[[Parameters], None]:
|
197
|
+
def __get_pvalidator_tagged_staircase(self) -> Callable[[Parameters], None]:
|
201
198
|
def pvalidator(parameters: Parameters) -> None:
|
202
199
|
validate_window(parameters)
|
203
200
|
|
204
|
-
freq_step
|
205
|
-
|
206
|
-
|
207
|
-
|
201
|
+
freq_step = cast(
|
202
|
+
float, parameters.get_parameter_value(PName.FREQUENCY_STEP)
|
203
|
+
)
|
204
|
+
sample_rate = cast(int, parameters.get_parameter_value(PName.SAMPLE_RATE))
|
205
|
+
min_samples_per_step = cast(
|
206
|
+
int, parameters.get_parameter_value(PName.MIN_SAMPLES_PER_STEP)
|
207
|
+
)
|
208
|
+
max_samples_per_step = cast(
|
209
|
+
int, parameters.get_parameter_value(PName.MAX_SAMPLES_PER_STEP)
|
210
|
+
)
|
208
211
|
|
209
212
|
if freq_step != sample_rate:
|
210
|
-
raise ValueError(
|
211
|
-
|
212
|
-
|
213
|
+
raise ValueError(
|
214
|
+
f"The frequency step must be equal to the sampling rate"
|
215
|
+
)
|
216
|
+
|
213
217
|
if min_samples_per_step > max_samples_per_step:
|
214
|
-
raise ValueError(
|
215
|
-
|
216
|
-
|
218
|
+
raise ValueError(
|
219
|
+
(
|
220
|
+
f"Minimum samples per step cannot be greater than the maximum samples per step. "
|
221
|
+
f"Got {min_samples_per_step}, which is greater than {max_samples_per_step}"
|
222
|
+
)
|
223
|
+
)
|
224
|
+
|
217
225
|
return pvalidator
|
218
|
-
|
@@ -1,171 +1,180 @@
|
|
1
|
-
# SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
|
1
|
+
# SPDX-FileCopyrightText: © 2024-2025 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
|
2
2
|
# This file is part of SPECTRE
|
3
3
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
4
4
|
|
5
5
|
from typing import Callable, overload
|
6
6
|
|
7
7
|
from spectre_core.capture_configs import (
|
8
|
-
CaptureTemplate,
|
9
|
-
|
8
|
+
CaptureTemplate,
|
9
|
+
CaptureMode,
|
10
|
+
Parameters,
|
11
|
+
Bound,
|
12
|
+
PName,
|
13
|
+
get_base_capture_template,
|
14
|
+
get_base_ptemplate,
|
15
|
+
OneOf,
|
10
16
|
validate_sample_rate_with_master_clock_rate,
|
11
|
-
validate_fixed_center_frequency,
|
17
|
+
validate_fixed_center_frequency,
|
18
|
+
validate_swept_center_frequency,
|
12
19
|
)
|
13
20
|
from .._base import BaseReceiver
|
14
21
|
from .._spec_names import SpecName
|
15
22
|
|
16
23
|
|
17
24
|
def get_pvalidator_fixed_center_frequency(
|
18
|
-
usrp_receiver: BaseReceiver
|
25
|
+
usrp_receiver: BaseReceiver,
|
19
26
|
) -> Callable[[Parameters], None]:
|
20
27
|
def pvalidator(parameters: Parameters) -> None:
|
21
28
|
validate_fixed_center_frequency(parameters)
|
22
29
|
validate_sample_rate_with_master_clock_rate(parameters)
|
30
|
+
|
23
31
|
return pvalidator
|
24
32
|
|
25
33
|
|
26
34
|
def get_pvalidator_swept_center_frequency(
|
27
|
-
usrp_receiver: BaseReceiver
|
35
|
+
usrp_receiver: BaseReceiver,
|
28
36
|
) -> Callable[[Parameters], None]:
|
29
37
|
def pvalidator(parameters: Parameters) -> None:
|
30
|
-
validate_swept_center_frequency(
|
31
|
-
|
38
|
+
validate_swept_center_frequency(
|
39
|
+
parameters, usrp_receiver.get_spec(SpecName.API_RETUNING_LATENCY)
|
40
|
+
)
|
32
41
|
validate_sample_rate_with_master_clock_rate(parameters)
|
42
|
+
|
33
43
|
return pvalidator
|
34
44
|
|
35
45
|
|
36
46
|
def get_capture_template_fixed_center_frequency(
|
37
|
-
usrp_receiver: BaseReceiver
|
47
|
+
usrp_receiver: BaseReceiver,
|
38
48
|
) -> CaptureTemplate:
|
39
|
-
|
40
|
-
capture_template = get_base_capture_template(
|
41
|
-
capture_template.add_ptemplate(
|
42
|
-
capture_template.add_ptemplate(
|
43
|
-
capture_template.add_ptemplate(
|
44
|
-
capture_template.add_ptemplate(
|
49
|
+
|
50
|
+
capture_template = get_base_capture_template(CaptureMode.FIXED_CENTER_FREQUENCY)
|
51
|
+
capture_template.add_ptemplate(get_base_ptemplate(PName.BANDWIDTH))
|
52
|
+
capture_template.add_ptemplate(get_base_ptemplate(PName.GAIN))
|
53
|
+
capture_template.add_ptemplate(get_base_ptemplate(PName.WIRE_FORMAT))
|
54
|
+
capture_template.add_ptemplate(get_base_ptemplate(PName.MASTER_CLOCK_RATE))
|
45
55
|
|
46
56
|
# TODO: Delegate defaults to receiver subclasses. Currently, these are sensible defaults for the b200mini
|
47
57
|
capture_template.set_defaults(
|
48
|
-
(PName.BATCH_SIZE,
|
49
|
-
(PName.CENTER_FREQUENCY,
|
50
|
-
(PName.SAMPLE_RATE,
|
51
|
-
(PName.BANDWIDTH,
|
52
|
-
(PName.WINDOW_HOP,
|
53
|
-
(PName.WINDOW_SIZE,
|
54
|
-
(PName.WINDOW_TYPE,
|
55
|
-
(PName.GAIN,
|
56
|
-
(PName.WIRE_FORMAT,
|
57
|
-
(PName.MASTER_CLOCK_RATE,
|
58
|
-
)
|
58
|
+
(PName.BATCH_SIZE, 4.0),
|
59
|
+
(PName.CENTER_FREQUENCY, 95800000),
|
60
|
+
(PName.SAMPLE_RATE, 2000000),
|
61
|
+
(PName.BANDWIDTH, 2000000),
|
62
|
+
(PName.WINDOW_HOP, 512),
|
63
|
+
(PName.WINDOW_SIZE, 1024),
|
64
|
+
(PName.WINDOW_TYPE, "blackman"),
|
65
|
+
(PName.GAIN, 35),
|
66
|
+
(PName.WIRE_FORMAT, "sc16"),
|
67
|
+
(PName.MASTER_CLOCK_RATE, 40e6),
|
68
|
+
)
|
59
69
|
|
60
70
|
capture_template.add_pconstraint(
|
61
71
|
PName.CENTER_FREQUENCY,
|
62
72
|
[
|
63
73
|
Bound(
|
64
74
|
lower_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
|
65
|
-
upper_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
|
75
|
+
upper_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND),
|
66
76
|
)
|
67
|
-
]
|
77
|
+
],
|
68
78
|
)
|
69
79
|
capture_template.add_pconstraint(
|
70
80
|
PName.SAMPLE_RATE,
|
71
81
|
[
|
72
82
|
Bound(
|
73
83
|
lower_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_LOWER_BOUND),
|
74
|
-
upper_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND)
|
84
|
+
upper_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND),
|
75
85
|
)
|
76
|
-
]
|
86
|
+
],
|
77
87
|
)
|
78
88
|
capture_template.add_pconstraint(
|
79
89
|
PName.BANDWIDTH,
|
80
90
|
[
|
81
91
|
Bound(
|
82
|
-
lower_bound=usrp_receiver.get_spec(
|
83
|
-
upper_bound=usrp_receiver.get_spec(
|
92
|
+
lower_bound=usrp_receiver.get_spec(SpecName.BANDWIDTH_LOWER_BOUND),
|
93
|
+
upper_bound=usrp_receiver.get_spec(SpecName.BANDWIDTH_UPPER_BOUND),
|
84
94
|
)
|
85
|
-
]
|
95
|
+
],
|
86
96
|
)
|
87
97
|
capture_template.add_pconstraint(
|
88
98
|
PName.GAIN,
|
89
99
|
[
|
90
100
|
Bound(
|
91
101
|
lower_bound=0,
|
92
|
-
upper_bound=usrp_receiver.get_spec(
|
102
|
+
upper_bound=usrp_receiver.get_spec(SpecName.GAIN_UPPER_BOUND),
|
93
103
|
)
|
94
|
-
]
|
104
|
+
],
|
95
105
|
)
|
96
106
|
capture_template.add_pconstraint(
|
97
|
-
PName.WIRE_FORMAT,
|
98
|
-
[
|
99
|
-
OneOf(
|
100
|
-
usrp_receiver.get_spec( SpecName.WIRE_FORMATS )
|
101
|
-
)
|
102
|
-
]
|
107
|
+
PName.WIRE_FORMAT, [OneOf(usrp_receiver.get_spec(SpecName.WIRE_FORMATS))]
|
103
108
|
)
|
104
109
|
capture_template.add_pconstraint(
|
105
110
|
PName.MASTER_CLOCK_RATE,
|
106
111
|
[
|
107
112
|
Bound(
|
108
|
-
lower_bound=usrp_receiver.get_spec(
|
109
|
-
|
113
|
+
lower_bound=usrp_receiver.get_spec(
|
114
|
+
SpecName.MASTER_CLOCK_RATE_LOWER_BOUND
|
115
|
+
),
|
116
|
+
upper_bound=usrp_receiver.get_spec(
|
117
|
+
SpecName.MASTER_CLOCK_RATE_UPPER_BOUND
|
118
|
+
),
|
110
119
|
)
|
111
|
-
]
|
120
|
+
],
|
112
121
|
)
|
113
122
|
return capture_template
|
114
123
|
|
115
124
|
|
116
125
|
def get_capture_template_swept_center_frequency(
|
117
|
-
usrp_receiver: BaseReceiver
|
126
|
+
usrp_receiver: BaseReceiver,
|
118
127
|
) -> CaptureTemplate:
|
119
128
|
|
120
|
-
capture_template = get_base_capture_template(
|
121
|
-
capture_template.add_ptemplate(
|
122
|
-
capture_template.add_ptemplate(
|
123
|
-
capture_template.add_ptemplate(
|
124
|
-
capture_template.add_ptemplate(
|
129
|
+
capture_template = get_base_capture_template(CaptureMode.SWEPT_CENTER_FREQUENCY)
|
130
|
+
capture_template.add_ptemplate(get_base_ptemplate(PName.BANDWIDTH))
|
131
|
+
capture_template.add_ptemplate(get_base_ptemplate(PName.GAIN))
|
132
|
+
capture_template.add_ptemplate(get_base_ptemplate(PName.WIRE_FORMAT))
|
133
|
+
capture_template.add_ptemplate(get_base_ptemplate(PName.MASTER_CLOCK_RATE))
|
125
134
|
|
126
135
|
# TODO: Delegate defaults to receiver subclasses. Currently, these are sensible defaults for the b200mini
|
127
136
|
capture_template.set_defaults(
|
128
|
-
(PName.BATCH_SIZE,
|
129
|
-
(PName.MIN_FREQUENCY,
|
130
|
-
(PName.MAX_FREQUENCY,
|
131
|
-
(PName.SAMPLES_PER_STEP,
|
132
|
-
(PName.FREQUENCY_STEP,
|
133
|
-
(PName.SAMPLE_RATE,
|
134
|
-
(PName.BANDWIDTH,
|
135
|
-
(PName.WINDOW_HOP,
|
136
|
-
(PName.WINDOW_SIZE,
|
137
|
-
(PName.WINDOW_TYPE,
|
138
|
-
(PName.GAIN,
|
139
|
-
(PName.WIRE_FORMAT,
|
140
|
-
(PName.MASTER_CLOCK_RATE,
|
141
|
-
)
|
137
|
+
(PName.BATCH_SIZE, 4.0),
|
138
|
+
(PName.MIN_FREQUENCY, 95000000),
|
139
|
+
(PName.MAX_FREQUENCY, 105000000),
|
140
|
+
(PName.SAMPLES_PER_STEP, 30000),
|
141
|
+
(PName.FREQUENCY_STEP, 2000000),
|
142
|
+
(PName.SAMPLE_RATE, 2000000),
|
143
|
+
(PName.BANDWIDTH, 2000000),
|
144
|
+
(PName.WINDOW_HOP, 512),
|
145
|
+
(PName.WINDOW_SIZE, 1024),
|
146
|
+
(PName.WINDOW_TYPE, "blackman"),
|
147
|
+
(PName.GAIN, 35),
|
148
|
+
(PName.WIRE_FORMAT, "sc16"),
|
149
|
+
(PName.MASTER_CLOCK_RATE, 40e6),
|
150
|
+
)
|
142
151
|
|
143
152
|
capture_template.add_pconstraint(
|
144
153
|
PName.MIN_FREQUENCY,
|
145
154
|
[
|
146
155
|
Bound(
|
147
156
|
lower_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
|
148
|
-
upper_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
|
157
|
+
upper_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND),
|
149
158
|
)
|
150
|
-
]
|
159
|
+
],
|
151
160
|
)
|
152
161
|
capture_template.add_pconstraint(
|
153
162
|
PName.MAX_FREQUENCY,
|
154
163
|
[
|
155
164
|
Bound(
|
156
165
|
lower_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
|
157
|
-
upper_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
|
166
|
+
upper_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND),
|
158
167
|
)
|
159
|
-
]
|
168
|
+
],
|
160
169
|
)
|
161
170
|
capture_template.add_pconstraint(
|
162
171
|
PName.SAMPLE_RATE,
|
163
172
|
[
|
164
173
|
Bound(
|
165
174
|
lower_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_LOWER_BOUND),
|
166
|
-
upper_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND)
|
175
|
+
upper_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND),
|
167
176
|
)
|
168
|
-
]
|
177
|
+
],
|
169
178
|
)
|
170
179
|
capture_template.add_pconstraint(
|
171
180
|
PName.BANDWIDTH,
|
@@ -174,32 +183,31 @@ def get_capture_template_swept_center_frequency(
|
|
174
183
|
lower_bound=usrp_receiver.get_spec(SpecName.BANDWIDTH_LOWER_BOUND),
|
175
184
|
upper_bound=usrp_receiver.get_spec(SpecName.BANDWIDTH_UPPER_BOUND),
|
176
185
|
)
|
177
|
-
]
|
186
|
+
],
|
178
187
|
)
|
179
188
|
capture_template.add_pconstraint(
|
180
189
|
PName.GAIN,
|
181
190
|
[
|
182
191
|
Bound(
|
183
192
|
lower_bound=0,
|
184
|
-
upper_bound=usrp_receiver.get_spec(
|
193
|
+
upper_bound=usrp_receiver.get_spec(SpecName.GAIN_UPPER_BOUND),
|
185
194
|
)
|
186
|
-
]
|
195
|
+
],
|
187
196
|
)
|
188
197
|
capture_template.add_pconstraint(
|
189
|
-
PName.WIRE_FORMAT,
|
190
|
-
[
|
191
|
-
OneOf(
|
192
|
-
usrp_receiver.get_spec( SpecName.WIRE_FORMATS )
|
193
|
-
)
|
194
|
-
]
|
198
|
+
PName.WIRE_FORMAT, [OneOf(usrp_receiver.get_spec(SpecName.WIRE_FORMATS))]
|
195
199
|
)
|
196
|
-
capture_template.add_pconstraint(
|
200
|
+
capture_template.add_pconstraint(
|
197
201
|
PName.MASTER_CLOCK_RATE,
|
198
202
|
[
|
199
|
-
Bound(
|
200
|
-
lower_bound=usrp_receiver.get_spec(
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
203
|
+
Bound(
|
204
|
+
lower_bound=usrp_receiver.get_spec(
|
205
|
+
SpecName.MASTER_CLOCK_RATE_LOWER_BOUND
|
206
|
+
),
|
207
|
+
upper_bound=usrp_receiver.get_spec(
|
208
|
+
SpecName.MASTER_CLOCK_RATE_UPPER_BOUND
|
209
|
+
),
|
210
|
+
)
|
211
|
+
],
|
212
|
+
)
|
205
213
|
return capture_template
|
@@ -1,3 +1,3 @@
|
|
1
|
-
# SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
|
1
|
+
# SPDX-FileCopyrightText: © 2024-2025 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
|
2
2
|
# This file is part of SPECTRE
|
3
|
-
# SPDX-License-Identifier: GPL-3.0-or-later
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|