spectre-core 0.0.9__py3-none-any.whl → 0.0.11__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.
Files changed (109) hide show
  1. spectre_core/__init__.py +0 -3
  2. spectre_core/_file_io/__init__.py +15 -0
  3. spectre_core/_file_io/file_handlers.py +128 -0
  4. spectre_core/capture_configs/__init__.py +29 -0
  5. spectre_core/capture_configs/_capture_config.py +85 -0
  6. spectre_core/capture_configs/_capture_templates.py +222 -0
  7. spectre_core/capture_configs/_parameters.py +110 -0
  8. spectre_core/capture_configs/_pconstraints.py +82 -0
  9. spectre_core/capture_configs/_ptemplates.py +450 -0
  10. spectre_core/capture_configs/_pvalidators.py +171 -0
  11. spectre_core/chunks/__init__.py +17 -201
  12. spectre_core/chunks/{base.py → _base.py} +15 -60
  13. spectre_core/chunks/_chunks.py +200 -0
  14. spectre_core/chunks/{factory.py → _factory.py} +6 -7
  15. spectre_core/chunks/library/{callisto/chunk.py → _callisto.py} +4 -7
  16. spectre_core/chunks/library/{fixed/chunk.py → _fixed_center_frequency.py} +7 -64
  17. spectre_core/chunks/library/_swept_center_frequency.py +103 -0
  18. spectre_core/config/__init__.py +20 -0
  19. spectre_core/config/_paths.py +77 -0
  20. spectre_core/config/_time_formats.py +15 -0
  21. spectre_core/exceptions.py +4 -5
  22. spectre_core/logging/__init__.py +11 -0
  23. spectre_core/logging/_configure.py +35 -0
  24. spectre_core/logging/_decorators.py +19 -0
  25. spectre_core/{logging.py → logging/_log_handlers.py} +13 -58
  26. spectre_core/plotting/__init__.py +7 -1
  27. spectre_core/plotting/{base.py → _base.py} +40 -20
  28. spectre_core/plotting/_format.py +18 -0
  29. spectre_core/plotting/{panel_stack.py → _panel_stack.py} +48 -48
  30. spectre_core/plotting/_panels.py +234 -0
  31. spectre_core/post_processing/__init__.py +10 -2
  32. spectre_core/post_processing/_base.py +119 -0
  33. spectre_core/post_processing/{factory.py → _factory.py} +7 -6
  34. spectre_core/post_processing/{post_processor.py → _post_processor.py} +3 -3
  35. spectre_core/post_processing/library/_fixed_center_frequency.py +115 -0
  36. spectre_core/post_processing/library/_swept_center_frequency.py +382 -0
  37. spectre_core/receivers/__init__.py +13 -2
  38. spectre_core/receivers/_base.py +180 -0
  39. spectre_core/receivers/{factory.py → _factory.py} +2 -2
  40. spectre_core/receivers/_spec_names.py +20 -0
  41. spectre_core/receivers/gr/__init__.py +3 -0
  42. spectre_core/receivers/gr/_base.py +33 -0
  43. spectre_core/receivers/gr/_rsp1a.py +158 -0
  44. spectre_core/receivers/gr/_rspduo.py +227 -0
  45. spectre_core/receivers/gr/_test.py +123 -0
  46. spectre_core/receivers/library/_rsp1a.py +61 -0
  47. spectre_core/receivers/library/_rspduo.py +69 -0
  48. spectre_core/receivers/library/_sdrplay_receiver.py +185 -0
  49. spectre_core/receivers/library/_test.py +221 -0
  50. spectre_core/spectrograms/__init__.py +18 -0
  51. spectre_core/spectrograms/{analytical.py → _analytical.py} +29 -27
  52. spectre_core/spectrograms/{array_operations.py → _array_operations.py} +47 -1
  53. spectre_core/spectrograms/{spectrogram.py → _spectrogram.py} +62 -35
  54. spectre_core/spectrograms/{transform.py → _transform.py} +76 -89
  55. spectre_core/{post_processing/library → wgetting}/__init__.py +4 -5
  56. spectre_core/wgetting/_callisto.py +155 -0
  57. {spectre_core-0.0.9.dist-info → spectre_core-0.0.11.dist-info}/METADATA +1 -1
  58. spectre_core-0.0.11.dist-info/RECORD +64 -0
  59. spectre_core/cfg.py +0 -116
  60. spectre_core/chunks/library/__init__.py +0 -8
  61. spectre_core/chunks/library/callisto/__init__.py +0 -0
  62. spectre_core/chunks/library/fixed/__init__.py +0 -0
  63. spectre_core/chunks/library/sweep/__init__.py +0 -0
  64. spectre_core/chunks/library/sweep/chunk.py +0 -400
  65. spectre_core/dynamic_imports.py +0 -22
  66. spectre_core/file_handlers/base.py +0 -68
  67. spectre_core/file_handlers/configs.py +0 -271
  68. spectre_core/file_handlers/json.py +0 -40
  69. spectre_core/file_handlers/text.py +0 -21
  70. spectre_core/plotting/factory.py +0 -26
  71. spectre_core/plotting/format.py +0 -19
  72. spectre_core/plotting/library/__init__.py +0 -7
  73. spectre_core/plotting/library/frequency_cuts/panel.py +0 -74
  74. spectre_core/plotting/library/integral_over_frequency/panel.py +0 -34
  75. spectre_core/plotting/library/spectrogram/panel.py +0 -92
  76. spectre_core/plotting/library/time_cuts/panel.py +0 -77
  77. spectre_core/plotting/panel_register.py +0 -13
  78. spectre_core/post_processing/base.py +0 -132
  79. spectre_core/post_processing/library/fixed/__init__.py +0 -0
  80. spectre_core/post_processing/library/fixed/event_handler.py +0 -40
  81. spectre_core/post_processing/library/sweep/event_handler.py +0 -54
  82. spectre_core/receivers/base.py +0 -422
  83. spectre_core/receivers/library/__init__.py +0 -7
  84. spectre_core/receivers/library/rsp1a/__init__.py +0 -0
  85. spectre_core/receivers/library/rsp1a/gr/__init__.py +0 -0
  86. spectre_core/receivers/library/rsp1a/gr/fixed.py +0 -104
  87. spectre_core/receivers/library/rsp1a/gr/sweep.py +0 -129
  88. spectre_core/receivers/library/rsp1a/receiver.py +0 -68
  89. spectre_core/receivers/library/rspduo/__init__.py +0 -0
  90. spectre_core/receivers/library/rspduo/gr/__init__.py +0 -0
  91. spectre_core/receivers/library/rspduo/gr/tuner_1_fixed.py +0 -114
  92. spectre_core/receivers/library/rspduo/gr/tuner_1_sweep.py +0 -131
  93. spectre_core/receivers/library/rspduo/gr/tuner_2_fixed.py +0 -120
  94. spectre_core/receivers/library/rspduo/gr/tuner_2_sweep.py +0 -119
  95. spectre_core/receivers/library/rspduo/receiver.py +0 -97
  96. spectre_core/receivers/library/test/__init__.py +0 -0
  97. spectre_core/receivers/library/test/gr/__init__.py +0 -0
  98. spectre_core/receivers/library/test/gr/cosine_signal_1.py +0 -83
  99. spectre_core/receivers/library/test/gr/tagged_staircase.py +0 -93
  100. spectre_core/receivers/library/test/receiver.py +0 -203
  101. spectre_core/receivers/validators.py +0 -231
  102. spectre_core/web_fetch/callisto.py +0 -101
  103. spectre_core-0.0.9.dist-info/RECORD +0 -74
  104. /spectre_core/chunks/{chunk_register.py → _register.py} +0 -0
  105. /spectre_core/post_processing/{event_handler_register.py → _register.py} +0 -0
  106. /spectre_core/receivers/{receiver_register.py → _register.py} +0 -0
  107. {spectre_core-0.0.9.dist-info → spectre_core-0.0.11.dist-info}/LICENSE +0 -0
  108. {spectre_core-0.0.9.dist-info → spectre_core-0.0.11.dist-info}/WHEEL +0 -0
  109. {spectre_core-0.0.9.dist-info → spectre_core-0.0.11.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,180 @@
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
@@ -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,3 @@
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
@@ -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
+ # RSP1A 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, 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
+
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, 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)
@@ -0,0 +1,227 @@
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
+ # RSPduo 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
+
31
+ class _tuner_1_fixed_center_frequency(gr.top_block):
32
+ def __init__(self,
33
+ tag: str,
34
+ parameters: Parameters):
35
+ gr.top_block.__init__(self, catch_exceptions=True)
36
+ gr.top_block.__init__(self, "tuner_1_fixed", catch_exceptions=True)
37
+
38
+ ##################################################
39
+ # Unpack capture config
40
+ ##################################################
41
+ sample_rate = parameters.get_parameter_value(PNames.SAMPLE_RATE)
42
+ batch_size = parameters.get_parameter_value(PNames.BATCH_SIZE)
43
+ center_freq = parameters.get_parameter_value(PNames.CENTER_FREQUENCY)
44
+ bandwidth = parameters.get_parameter_value(PNames.BANDWIDTH)
45
+ if_gain = parameters.get_parameter_value(PNames.IF_GAIN)
46
+ rf_gain = parameters.get_parameter_value(PNames.RF_GAIN)
47
+
48
+ ##################################################
49
+ # Blocks
50
+ ##################################################
51
+ self.spectre_batched_file_sink_0 = spectre.batched_file_sink(get_chunks_dir_path(),
52
+ tag,
53
+ batch_size,
54
+ sample_rate)
55
+ self.sdrplay3_rspduo_0 = sdrplay3.rspduo(
56
+ '',
57
+ rspduo_mode="Single Tuner",
58
+ antenna="Tuner 1 50 ohm",
59
+ stream_args=sdrplay3.stream_args(
60
+ output_type='fc32',
61
+ channels_size=1
62
+ ),
63
+ )
64
+ self.sdrplay3_rspduo_0.set_sample_rate(sample_rate)
65
+ self.sdrplay3_rspduo_0.set_center_freq(center_freq)
66
+ self.sdrplay3_rspduo_0.set_bandwidth(bandwidth)
67
+ self.sdrplay3_rspduo_0.set_antenna("Tuner 1 50 ohm")
68
+ self.sdrplay3_rspduo_0.set_gain_mode(False)
69
+ self.sdrplay3_rspduo_0.set_gain(if_gain, 'IF')
70
+ self.sdrplay3_rspduo_0.set_gain(rf_gain, 'RF')
71
+ self.sdrplay3_rspduo_0.set_freq_corr(0)
72
+ self.sdrplay3_rspduo_0.set_dc_offset_mode(False)
73
+ self.sdrplay3_rspduo_0.set_iq_balance_mode(False)
74
+ self.sdrplay3_rspduo_0.set_agc_setpoint(-30)
75
+ self.sdrplay3_rspduo_0.set_rf_notch_filter(False)
76
+ self.sdrplay3_rspduo_0.set_dab_notch_filter(False)
77
+ self.sdrplay3_rspduo_0.set_am_notch_filter(False)
78
+ self.sdrplay3_rspduo_0.set_biasT(False)
79
+ self.sdrplay3_rspduo_0.set_debug_mode(False)
80
+ self.sdrplay3_rspduo_0.set_sample_sequence_gaps_check(False)
81
+ self.sdrplay3_rspduo_0.set_show_gain_changes(False)
82
+
83
+
84
+ ##################################################
85
+ # Connections
86
+ ##################################################
87
+ self.connect((self.sdrplay3_rspduo_0, 0), (self.spectre_batched_file_sink_0, 0))
88
+
89
+
90
+ class _tuner_2_fixed_center_frequency(gr.top_block):
91
+ def __init__(self,
92
+ tag: str,
93
+ parameters: Parameters):
94
+ gr.top_block.__init__(self, catch_exceptions=True)
95
+ gr.top_block.__init__(self, "tuner_1_fixed", catch_exceptions=True)
96
+
97
+ ##################################################
98
+ # Unpack capture config
99
+ ##################################################
100
+ sample_rate = parameters.get_parameter_value(PNames.SAMPLE_RATE)
101
+ batch_size = parameters.get_parameter_value(PNames.BATCH_SIZE)
102
+ center_freq = parameters.get_parameter_value(PNames.CENTER_FREQUENCY)
103
+ bandwidth = parameters.get_parameter_value(PNames.BANDWIDTH)
104
+ if_gain = parameters.get_parameter_value(PNames.IF_GAIN)
105
+ rf_gain = parameters.get_parameter_value(PNames.RF_GAIN)
106
+
107
+ ##################################################
108
+ # Blocks
109
+ ##################################################
110
+ self.spectre_batched_file_sink_0 = spectre.batched_file_sink(get_chunks_dir_path(),
111
+ tag,
112
+ batch_size,
113
+ sample_rate)
114
+ self.sdrplay3_rspduo_0 = sdrplay3.rspduo(
115
+ '',
116
+ rspduo_mode="Single Tuner",
117
+ antenna="Tuner 2 50 ohm",
118
+ stream_args=sdrplay3.stream_args(
119
+ output_type='fc32',
120
+ channels_size=1
121
+ ),
122
+ )
123
+ self.sdrplay3_rspduo_0.set_sample_rate(sample_rate)
124
+ self.sdrplay3_rspduo_0.set_center_freq(center_freq)
125
+ self.sdrplay3_rspduo_0.set_bandwidth(bandwidth)
126
+ self.sdrplay3_rspduo_0.set_antenna("Tuner 2 50 ohm")
127
+ self.sdrplay3_rspduo_0.set_gain_mode(False)
128
+ self.sdrplay3_rspduo_0.set_gain(if_gain, 'IF')
129
+ self.sdrplay3_rspduo_0.set_gain(rf_gain, 'RF', False)
130
+ self.sdrplay3_rspduo_0.set_freq_corr(0)
131
+ self.sdrplay3_rspduo_0.set_dc_offset_mode(False)
132
+ self.sdrplay3_rspduo_0.set_iq_balance_mode(False)
133
+ self.sdrplay3_rspduo_0.set_agc_setpoint(-30)
134
+ self.sdrplay3_rspduo_0.set_rf_notch_filter(False)
135
+ self.sdrplay3_rspduo_0.set_dab_notch_filter(False)
136
+ self.sdrplay3_rspduo_0.set_am_notch_filter(False)
137
+ self.sdrplay3_rspduo_0.set_biasT(False)
138
+ self.sdrplay3_rspduo_0.set_stream_tags(False)
139
+ self.sdrplay3_rspduo_0.set_debug_mode(False)
140
+ self.sdrplay3_rspduo_0.set_sample_sequence_gaps_check(False)
141
+ self.sdrplay3_rspduo_0.set_show_gain_changes(False)
142
+
143
+
144
+ ##################################################
145
+ # Connections
146
+ ##################################################
147
+ self.connect((self.sdrplay3_rspduo_0, 0), (self.spectre_batched_file_sink_0, 0))
148
+
149
+
150
+ class _tuner_1_swept_center_frequency(gr.top_block):
151
+ def __init__(self,
152
+ tag: str,
153
+ parameters: Parameters):
154
+ gr.top_block.__init__(self, catch_exceptions=True)
155
+
156
+ ##################################################
157
+ # Unpack capture config
158
+ ##################################################
159
+ sample_rate = parameters.get_parameter_value(PNames.SAMPLE_RATE)
160
+ bandwidth = parameters.get_parameter_value(PNames.BANDWIDTH)
161
+ min_frequency = parameters.get_parameter_value(PNames.MIN_FREQUENCY)
162
+ max_frequency = parameters.get_parameter_value(PNames.MAX_FREQUENCY)
163
+ frequency_step = parameters.get_parameter_value(PNames.FREQUENCY_STEP)
164
+ samples_per_step = parameters.get_parameter_value(PNames.SAMPLES_PER_STEP)
165
+ if_gain = parameters.get_parameter_value(PNames.IF_GAIN)
166
+ rf_gain = parameters.get_parameter_value(PNames.RF_GAIN)
167
+ batch_size = parameters.get_parameter_value(PNames.BATCH_SIZE)
168
+
169
+ ##################################################
170
+ # Blocks
171
+ ##################################################
172
+ self.spectre_sweep_driver_0 = spectre.sweep_driver(min_frequency,
173
+ max_frequency,
174
+ frequency_step,
175
+ sample_rate,
176
+ samples_per_step,
177
+ 'freq')
178
+ self.spectre_batched_file_sink_0 = spectre.batched_file_sink(get_chunks_dir_path(),
179
+ tag,
180
+ batch_size,
181
+ sample_rate,
182
+ True,
183
+ 'freq',
184
+ min_frequency)
185
+ self.sdrplay3_rspduo_0 = sdrplay3.rspduo(
186
+ '',
187
+ rspduo_mode="Single Tuner",
188
+ antenna="Tuner 1 50 ohm",
189
+ stream_args=sdrplay3.stream_args(
190
+ output_type='fc32',
191
+ channels_size=1
192
+ ),
193
+ )
194
+ self.sdrplay3_rspduo_0.set_sample_rate(sample_rate, True)
195
+ self.sdrplay3_rspduo_0.set_center_freq(min_frequency, True)
196
+ self.sdrplay3_rspduo_0.set_bandwidth(bandwidth)
197
+ self.sdrplay3_rspduo_0.set_antenna("Tuner 1 50 ohm")
198
+ self.sdrplay3_rspduo_0.set_gain_mode(False)
199
+ self.sdrplay3_rspduo_0.set_gain(if_gain, 'IF', True)
200
+ self.sdrplay3_rspduo_0.set_gain(rf_gain, 'RF', True)
201
+ self.sdrplay3_rspduo_0.set_freq_corr(0)
202
+ self.sdrplay3_rspduo_0.set_dc_offset_mode(False)
203
+ self.sdrplay3_rspduo_0.set_iq_balance_mode(False)
204
+ self.sdrplay3_rspduo_0.set_agc_setpoint(-30)
205
+ self.sdrplay3_rspduo_0.set_rf_notch_filter(False)
206
+ self.sdrplay3_rspduo_0.set_dab_notch_filter(True)
207
+ self.sdrplay3_rspduo_0.set_am_notch_filter(False)
208
+ self.sdrplay3_rspduo_0.set_biasT(False)
209
+ self.sdrplay3_rspduo_0.set_stream_tags(True)
210
+ self.sdrplay3_rspduo_0.set_debug_mode(False)
211
+ self.sdrplay3_rspduo_0.set_sample_sequence_gaps_check(False)
212
+ self.sdrplay3_rspduo_0.set_show_gain_changes(False)
213
+
214
+
215
+ ##################################################
216
+ # Connections
217
+ ##################################################
218
+ self.msg_connect((self.spectre_sweep_driver_0, 'freq'), (self.sdrplay3_rspduo_0, 'freq'))
219
+ self.connect((self.sdrplay3_rspduo_0, 0), (self.spectre_batched_file_sink_0, 0))
220
+ self.connect((self.sdrplay3_rspduo_0, 0), (self.spectre_sweep_driver_0, 0))
221
+
222
+
223
+ @dataclass(frozen=True)
224
+ class CaptureMethods:
225
+ tuner_1_fixed_center_frequency = partial(capture, top_block_cls=_tuner_1_fixed_center_frequency)
226
+ tuner_2_fixed_center_frequency = partial(capture, top_block_cls=_tuner_2_fixed_center_frequency)
227
+ tuner_1_swept_center_frequency = partial(capture, top_block_cls=_tuner_1_swept_center_frequency)