spectre-core 0.0.15__tar.gz → 0.0.16__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. {spectre_core-0.0.15 → spectre_core-0.0.16}/PKG-INFO +1 -1
  2. {spectre_core-0.0.15 → spectre_core-0.0.16}/pyproject.toml +1 -1
  3. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/capture_configs/__init__.py +3 -3
  4. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_pnames.py +3 -1
  5. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_ptemplates.py +16 -6
  6. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_pvalidators.py +16 -0
  7. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/_base.py +1 -1
  8. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/_spec_names.py +18 -10
  9. spectre_core-0.0.16/src/spectre_core/receivers/plugins/_b200mini.py +84 -0
  10. spectre_core-0.0.16/src/spectre_core/receivers/plugins/_usrp.py +205 -0
  11. spectre_core-0.0.16/src/spectre_core/receivers/plugins/gr/_usrp.py +139 -0
  12. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core.egg-info/PKG-INFO +1 -1
  13. spectre_core-0.0.15/src/spectre_core/receivers/plugins/_b200mini.py +0 -72
  14. spectre_core-0.0.15/src/spectre_core/receivers/plugins/_usrp.py +0 -70
  15. spectre_core-0.0.15/src/spectre_core/receivers/plugins/gr/_usrp.py +0 -62
  16. {spectre_core-0.0.15 → spectre_core-0.0.16}/LICENSE +0 -0
  17. {spectre_core-0.0.15 → spectre_core-0.0.16}/README.md +0 -0
  18. {spectre_core-0.0.15 → spectre_core-0.0.16}/setup.cfg +0 -0
  19. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/__init__.py +0 -0
  20. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/_file_io/__init__.py +0 -0
  21. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/_file_io/file_handlers.py +0 -0
  22. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/batches/__init__.py +0 -0
  23. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/batches/_base.py +0 -0
  24. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/batches/_batches.py +0 -0
  25. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/batches/_factory.py +0 -0
  26. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/batches/_register.py +0 -0
  27. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/batches/plugins/_batch_keys.py +0 -0
  28. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/batches/plugins/_callisto.py +0 -0
  29. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/batches/plugins/_iq_stream.py +0 -0
  30. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_capture_config.py +0 -0
  31. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_capture_modes.py +0 -0
  32. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_capture_templates.py +0 -0
  33. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_parameters.py +0 -0
  34. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_pconstraints.py +0 -0
  35. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/config/__init__.py +0 -0
  36. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/config/_paths.py +0 -0
  37. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/config/_time_formats.py +0 -0
  38. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/exceptions.py +0 -0
  39. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/jobs/__init__.py +0 -0
  40. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/jobs/_jobs.py +0 -0
  41. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/jobs/_workers.py +0 -0
  42. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/logs/__init__.py +0 -0
  43. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/logs/_configure.py +0 -0
  44. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/logs/_decorators.py +0 -0
  45. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/logs/_logs.py +0 -0
  46. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/logs/_process_types.py +0 -0
  47. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/plotting/__init__.py +0 -0
  48. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/plotting/_base.py +0 -0
  49. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/plotting/_format.py +0 -0
  50. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/plotting/_panel_names.py +0 -0
  51. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/plotting/_panel_stack.py +0 -0
  52. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/plotting/_panels.py +0 -0
  53. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/post_processing/__init__.py +0 -0
  54. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/post_processing/_base.py +0 -0
  55. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/post_processing/_factory.py +0 -0
  56. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/post_processing/_post_processor.py +0 -0
  57. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/post_processing/_register.py +0 -0
  58. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/post_processing/plugins/_event_handler_keys.py +0 -0
  59. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/post_processing/plugins/_fixed_center_frequency.py +0 -0
  60. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/post_processing/plugins/_swept_center_frequency.py +0 -0
  61. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/py.typed +0 -0
  62. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/__init__.py +0 -0
  63. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/_factory.py +0 -0
  64. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/_register.py +0 -0
  65. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/__init__.py +0 -0
  66. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/_receiver_names.py +0 -0
  67. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/_rsp1a.py +0 -0
  68. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/_rspduo.py +0 -0
  69. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/_sdrplay_receiver.py +0 -0
  70. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/_test.py +0 -0
  71. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/gr/__init__.py +0 -0
  72. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/gr/_base.py +0 -0
  73. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/gr/_rsp1a.py +0 -0
  74. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/gr/_rspduo.py +0 -0
  75. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/gr/_test.py +0 -0
  76. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/spectrograms/__init__.py +0 -0
  77. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/spectrograms/_analytical.py +0 -0
  78. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/spectrograms/_array_operations.py +0 -0
  79. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/spectrograms/_spectrogram.py +0 -0
  80. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/spectrograms/_transform.py +0 -0
  81. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/wgetting/__init__.py +0 -0
  82. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core/wgetting/_callisto.py +0 -0
  83. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core.egg-info/SOURCES.txt +0 -0
  84. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core.egg-info/dependency_links.txt +0 -0
  85. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core.egg-info/requires.txt +0 -0
  86. {spectre_core-0.0.15 → spectre_core-0.0.16}/src/spectre_core.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: spectre-core
3
- Version: 0.0.15
3
+ Version: 0.0.16
4
4
  Summary: The core Python package used by the spectre program.
5
5
  Maintainer-email: Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "spectre-core"
7
- version = "0.0.15"
7
+ version = "0.0.16"
8
8
  maintainers = [
9
9
  { name="Jimmy Fitzpatrick", email="jcfitzpatrick12@gmail.com" },
10
10
  ]
@@ -9,7 +9,7 @@ from ._capture_modes import CaptureMode
9
9
  from ._pvalidators import (
10
10
  validate_fixed_center_frequency, validate_non_overlapping_steps, validate_num_samples_per_step,
11
11
  validate_num_steps_per_sweep, validate_nyquist_criterion, validate_step_interval, validate_sweep_interval,
12
- validate_swept_center_frequency, validate_window
12
+ validate_swept_center_frequency, validate_window, validate_sample_rate_with_master_clock_rate
13
13
  )
14
14
  from ._capture_config import CaptureConfig
15
15
  from ._ptemplates import PTemplate, get_base_ptemplate
@@ -29,5 +29,5 @@ __all__ = [
29
29
  "PConstraint", "PConstraint", "Bound", "OneOf", "EnforceSign", "PowerOfTwo", "make_base_capture_template", "PName",
30
30
  "get_base_ptemplate", "BasePConstraint", "validate_fixed_center_frequency", "validate_non_overlapping_steps",
31
31
  "validate_num_samples_per_step", "validate_num_steps_per_sweep", "validate_nyquist_criterion", "validate_step_interval",
32
- "validate_sweep_interval", "validate_swept_center_frequency", "validate_window"
33
- ]
32
+ "validate_sweep_interval", "validate_swept_center_frequency", "validate_window", "validate_sample_rate_with_master_clock_rate"
33
+ ]
@@ -47,4 +47,6 @@ class PName(Enum):
47
47
  OBS_LAT = "obs_lat"
48
48
  OBS_LON = "obs_lon"
49
49
  OBS_ALT = "obs_alt"
50
- NORMALISED_GAIN = "normalised_gain"
50
+ GAIN = "gain"
51
+ MASTER_CLOCK_RATE = "master_clock_rate"
52
+ WIRE_FORMAT = "wire_format"
@@ -300,14 +300,24 @@ _base_ptemplates: dict[PName, PTemplate] = {
300
300
  pconstraints=[
301
301
  EnforceSign.non_positive
302
302
  ]),
303
- PName.NORMALISED_GAIN: PTemplate(PName.NORMALISED_GAIN,
303
+ PName.GAIN: PTemplate(PName.GAIN,
304
304
  float,
305
305
  help = """
306
- The normalised gain value, where 1.0 is mapped to the max gain of the receiver being used.
307
- """,
308
- pconstraints=[
309
- Bound(0.0, 1.0)
310
- ]),
306
+ The gain value for the SDR, in dB
307
+ """
308
+ ),
309
+ PName.MASTER_CLOCK_RATE: PTemplate(PName.MASTER_CLOCK_RATE,
310
+ int,
311
+ help = """
312
+ The primary reference clock for the SDR, specified in Hz.
313
+ """
314
+ ),
315
+ PName.WIRE_FORMAT: PTemplate(PName.WIRE_FORMAT,
316
+ str,
317
+ help = """
318
+ Controls the form of the data over the bus/network.
319
+ """
320
+ ),
311
321
  PName.EVENT_HANDLER_KEY: PTemplate(PName.EVENT_HANDLER_KEY,
312
322
  str,
313
323
  help = """
@@ -184,6 +184,22 @@ def validate_step_interval(
184
184
  f"derived api latency {api_retuning_latency} [s]; you may experience undefined behaviour!")
185
185
 
186
186
 
187
+ def validate_sample_rate_with_master_clock_rate(
188
+ parameters: Parameters,
189
+ ) -> None:
190
+ """Ensure that the master clock rate is an integer multiple of the sample rate.
191
+
192
+ :param parameters: The parameters to be validated.
193
+ :raises ValueError: If the master clock rate is not an integer multiple of the sample rate
194
+ """
195
+ master_clock_rate = cast(int, parameters.get_parameter_value(PName.MASTER_CLOCK_RATE))
196
+ sample_rate = cast(int, parameters.get_parameter_value(PName.SAMPLE_RATE))
197
+
198
+ if master_clock_rate % sample_rate != 0:
199
+ raise ValueError(f"The master clock rate of {master_clock_rate} [Hz] is not an integer "
200
+ f"multiple of the sample rate {sample_rate} [Hz].")
201
+
202
+
187
203
  def validate_fixed_center_frequency(
188
204
  parameters: Parameters
189
205
  ) -> None:
@@ -226,7 +226,7 @@ class BaseReceiver(ABC):
226
226
  def add_spec(
227
227
  self,
228
228
  name: SpecName,
229
- value: float|int|list[float|int]
229
+ value: Any
230
230
  ) -> None:
231
231
  """
232
232
  Add a hardware specification.
@@ -18,16 +18,24 @@ class SpecName(Enum):
18
18
  Negative values indicate attenuation.
19
19
  :ivar RF_GAIN_UPPER_BOUND: The upper bound for the radio frequency gain, in dB.
20
20
  Negative values indicate attenuation.
21
+ :ivar GAIN_UPPER_BOUND: The upper bound for the gain, in dB.
22
+ :ivar WIRE_FORMATS: Supported data types transferred over the bus/network.
23
+ :ivar MASTER_CLOCK_RATE_LOWER_BOUND: The lower bound for the SDR reference clock rate, in Hz.
24
+ :ivar MASTER_CLOCK_RATE_UPPER_BOUND: The upper bound for the SDR reference clock rate, in Hz.
21
25
  :ivar API_RETUNING_LATENCY: An empirical estimate of the delay between issuing a command
22
26
  for a receiver to retune its center frequency and the actual physical update of the center frequency.
23
27
  """
24
- FREQUENCY_LOWER_BOUND = "frequency_lower_bound"
25
- FREQUENCY_UPPER_BOUND = "frequency_upper_bound"
26
- SAMPLE_RATE_LOWER_BOUND = "sample_rate_lower_bound"
27
- SAMPLE_RATE_UPPER_BOUND = "sample_rate_upper_bound"
28
- BANDWIDTH_LOWER_BOUND = "bandwidth_lower_bound"
29
- BANDWIDTH_UPPER_BOUND = "bandwidth_upper_bound"
30
- BANDWIDTH_OPTIONS = "bandwidth_options"
31
- IF_GAIN_UPPER_BOUND = "if_gain_upper_bound"
32
- RF_GAIN_UPPER_BOUND = "rf_gain_upper_bound"
33
- API_RETUNING_LATENCY = "api_retuning_latency"
28
+ FREQUENCY_LOWER_BOUND = "frequency_lower_bound"
29
+ FREQUENCY_UPPER_BOUND = "frequency_upper_bound"
30
+ SAMPLE_RATE_LOWER_BOUND = "sample_rate_lower_bound"
31
+ SAMPLE_RATE_UPPER_BOUND = "sample_rate_upper_bound"
32
+ BANDWIDTH_LOWER_BOUND = "bandwidth_lower_bound"
33
+ BANDWIDTH_UPPER_BOUND = "bandwidth_upper_bound"
34
+ BANDWIDTH_OPTIONS = "bandwidth_options"
35
+ IF_GAIN_UPPER_BOUND = "if_gain_upper_bound"
36
+ RF_GAIN_UPPER_BOUND = "rf_gain_upper_bound"
37
+ GAIN_UPPER_BOUND = "gain_upper_bound"
38
+ WIRE_FORMATS = "wire_formats"
39
+ MASTER_CLOCK_RATE_LOWER_BOUND = "master_clock_rate_lower_bound"
40
+ MASTER_CLOCK_RATE_UPPER_BOUND = "master_clock_rate_upper_bound"
41
+ API_RETUNING_LATENCY = "api_retuning_latency"
@@ -0,0 +1,84 @@
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
+ from ._receiver_names import ReceiverName
8
+ from ._usrp import (
9
+ get_pvalidator_fixed_center_frequency, get_pvalidator_swept_center_frequency,
10
+ get_capture_template_fixed_center_frequency, get_capture_template_swept_center_frequency
11
+ )
12
+ from .gr._usrp import CaptureMethod
13
+ from .._spec_names import SpecName
14
+ from .._base import BaseReceiver
15
+ from .._register import register_receiver
16
+
17
+ @dataclass(frozen=True)
18
+ class Mode:
19
+ """An operating mode for the `B200mini` receiver."""
20
+ FIXED_CENTER_FREQUENCY = "fixed_center_frequency"
21
+ SWEPT_CENTER_FREQUENCY = "swept_center_frequency"
22
+
23
+
24
+ @register_receiver(ReceiverName.B200MINI)
25
+ class B200mini(BaseReceiver):
26
+ """Receiver implementation for the USRP B200mini (https://www.ettus.com/all-products/usrp-b200mini/)"""
27
+ def _add_specs(
28
+ self
29
+ ) -> None:
30
+ self.add_spec( SpecName.SAMPLE_RATE_LOWER_BOUND , 200e3 )
31
+ self.add_spec( SpecName.SAMPLE_RATE_UPPER_BOUND , 56e6 )
32
+ self.add_spec( SpecName.FREQUENCY_LOWER_BOUND , 70e6 )
33
+ self.add_spec( SpecName.FREQUENCY_UPPER_BOUND , 6e9 )
34
+ self.add_spec( SpecName.BANDWIDTH_LOWER_BOUND , 200e3 )
35
+ self.add_spec( SpecName.BANDWIDTH_UPPER_BOUND , 56e6 )
36
+ self.add_spec( SpecName.GAIN_UPPER_BOUND , 76 )
37
+ self.add_spec( SpecName.WIRE_FORMATS , ["sc8", "sc12", "sc16"])
38
+ self.add_spec( SpecName.MASTER_CLOCK_RATE_LOWER_BOUND, 5e6)
39
+ self.add_spec( SpecName.MASTER_CLOCK_RATE_UPPER_BOUND, 61.44e6)
40
+ self.add_spec( SpecName.API_RETUNING_LATENCY , 1e-5 ) # TODO: This is a ballpark, pending empirical testing
41
+
42
+
43
+ def _add_capture_methods(
44
+ self
45
+ ) -> None:
46
+ self.add_capture_method(Mode.FIXED_CENTER_FREQUENCY,
47
+ CaptureMethod.fixed_center_frequency)
48
+ self.add_capture_method(Mode.SWEPT_CENTER_FREQUENCY,
49
+ CaptureMethod.swept_center_frequency)
50
+
51
+
52
+ def _add_capture_templates(
53
+ self
54
+ ) -> None:
55
+ self.add_capture_template(Mode.FIXED_CENTER_FREQUENCY,
56
+ get_capture_template_fixed_center_frequency(self))
57
+ self.add_capture_template(Mode.SWEPT_CENTER_FREQUENCY,
58
+ get_capture_template_swept_center_frequency(self))
59
+
60
+
61
+ def _add_pvalidators(
62
+ self
63
+ ) -> None:
64
+ self.add_pvalidator(Mode.FIXED_CENTER_FREQUENCY,
65
+ get_pvalidator_fixed_center_frequency(self))
66
+ self.add_pvalidator(Mode.SWEPT_CENTER_FREQUENCY,
67
+ get_pvalidator_swept_center_frequency(self))
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+
80
+
81
+
82
+
83
+
84
+
@@ -0,0 +1,205 @@
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 typing import Callable, overload
6
+
7
+ from spectre_core.capture_configs import (
8
+ CaptureTemplate, CaptureMode, Parameters, Bound, PName,
9
+ get_base_capture_template, get_base_ptemplate, OneOf,
10
+ validate_sample_rate_with_master_clock_rate,
11
+ validate_fixed_center_frequency, validate_swept_center_frequency
12
+ )
13
+ from .._base import BaseReceiver
14
+ from .._spec_names import SpecName
15
+
16
+
17
+ def get_pvalidator_fixed_center_frequency(
18
+ usrp_receiver: BaseReceiver
19
+ ) -> Callable[[Parameters], None]:
20
+ def pvalidator(parameters: Parameters) -> None:
21
+ validate_fixed_center_frequency(parameters)
22
+ validate_sample_rate_with_master_clock_rate(parameters)
23
+ return pvalidator
24
+
25
+
26
+ def get_pvalidator_swept_center_frequency(
27
+ usrp_receiver: BaseReceiver
28
+ ) -> Callable[[Parameters], None]:
29
+ def pvalidator(parameters: Parameters) -> None:
30
+ validate_swept_center_frequency(parameters,
31
+ usrp_receiver.get_spec(SpecName.API_RETUNING_LATENCY))
32
+ validate_sample_rate_with_master_clock_rate(parameters)
33
+ return pvalidator
34
+
35
+
36
+ def get_capture_template_fixed_center_frequency(
37
+ usrp_receiver: BaseReceiver
38
+ ) -> CaptureTemplate:
39
+
40
+ capture_template = get_base_capture_template( CaptureMode.FIXED_CENTER_FREQUENCY )
41
+ capture_template.add_ptemplate( get_base_ptemplate(PName.BANDWIDTH) )
42
+ capture_template.add_ptemplate( get_base_ptemplate(PName.GAIN) )
43
+ capture_template.add_ptemplate( get_base_ptemplate(PName.WIRE_FORMAT) )
44
+ capture_template.add_ptemplate( get_base_ptemplate(PName.MASTER_CLOCK_RATE) )
45
+
46
+ # TODO: Delegate defaults to receiver subclasses. Currently, these are sensible defaults for the b200mini
47
+ capture_template.set_defaults(
48
+ (PName.BATCH_SIZE, 4.0),
49
+ (PName.CENTER_FREQUENCY, 95800000),
50
+ (PName.SAMPLE_RATE, 2000000),
51
+ (PName.BANDWIDTH, 2000000),
52
+ (PName.WINDOW_HOP, 512),
53
+ (PName.WINDOW_SIZE, 1024),
54
+ (PName.WINDOW_TYPE, "blackman"),
55
+ (PName.GAIN, 35),
56
+ (PName.WIRE_FORMAT, "sc16"),
57
+ (PName.MASTER_CLOCK_RATE, 40e6)
58
+ )
59
+
60
+ capture_template.add_pconstraint(
61
+ PName.CENTER_FREQUENCY,
62
+ [
63
+ Bound(
64
+ lower_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
65
+ upper_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
66
+ )
67
+ ]
68
+ )
69
+ capture_template.add_pconstraint(
70
+ PName.SAMPLE_RATE,
71
+ [
72
+ Bound(
73
+ lower_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_LOWER_BOUND),
74
+ upper_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND)
75
+ )
76
+ ]
77
+ )
78
+ capture_template.add_pconstraint(
79
+ PName.BANDWIDTH,
80
+ [
81
+ Bound(
82
+ lower_bound=usrp_receiver.get_spec( SpecName.BANDWIDTH_LOWER_BOUND ),
83
+ upper_bound=usrp_receiver.get_spec( SpecName.BANDWIDTH_UPPER_BOUND )
84
+ )
85
+ ]
86
+ )
87
+ capture_template.add_pconstraint(
88
+ PName.GAIN,
89
+ [
90
+ Bound(
91
+ lower_bound=0,
92
+ upper_bound=usrp_receiver.get_spec( SpecName.GAIN_UPPER_BOUND )
93
+ )
94
+ ]
95
+ )
96
+ capture_template.add_pconstraint(
97
+ PName.WIRE_FORMAT,
98
+ [
99
+ OneOf(
100
+ usrp_receiver.get_spec( SpecName.WIRE_FORMATS )
101
+ )
102
+ ]
103
+ )
104
+ capture_template.add_pconstraint(
105
+ PName.MASTER_CLOCK_RATE,
106
+ [
107
+ Bound(
108
+ lower_bound=usrp_receiver.get_spec( SpecName.MASTER_CLOCK_RATE_LOWER_BOUND ),
109
+ upper_bound=usrp_receiver.get_spec( SpecName.MASTER_CLOCK_RATE_UPPER_BOUND )
110
+ )
111
+ ]
112
+ )
113
+ return capture_template
114
+
115
+
116
+ def get_capture_template_swept_center_frequency(
117
+ usrp_receiver: BaseReceiver
118
+ ) -> CaptureTemplate:
119
+
120
+ capture_template = get_base_capture_template( CaptureMode.SWEPT_CENTER_FREQUENCY )
121
+ capture_template.add_ptemplate( get_base_ptemplate(PName.BANDWIDTH) )
122
+ capture_template.add_ptemplate( get_base_ptemplate(PName.GAIN) )
123
+ capture_template.add_ptemplate( get_base_ptemplate(PName.WIRE_FORMAT) )
124
+ capture_template.add_ptemplate( get_base_ptemplate(PName.MASTER_CLOCK_RATE) )
125
+
126
+ # TODO: Delegate defaults to receiver subclasses. Currently, these are sensible defaults for the b200mini
127
+ capture_template.set_defaults(
128
+ (PName.BATCH_SIZE, 4.0),
129
+ (PName.MIN_FREQUENCY, 95000000),
130
+ (PName.MAX_FREQUENCY, 105000000),
131
+ (PName.SAMPLES_PER_STEP, 30000),
132
+ (PName.FREQUENCY_STEP, 2000000),
133
+ (PName.SAMPLE_RATE, 2000000),
134
+ (PName.BANDWIDTH, 2000000),
135
+ (PName.WINDOW_HOP, 512),
136
+ (PName.WINDOW_SIZE, 1024),
137
+ (PName.WINDOW_TYPE, "blackman"),
138
+ (PName.GAIN, 35),
139
+ (PName.WIRE_FORMAT, "sc16"),
140
+ (PName.MASTER_CLOCK_RATE, 40e6)
141
+ )
142
+
143
+ capture_template.add_pconstraint(
144
+ PName.MIN_FREQUENCY,
145
+ [
146
+ Bound(
147
+ lower_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
148
+ upper_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
149
+ )
150
+ ]
151
+ )
152
+ capture_template.add_pconstraint(
153
+ PName.MAX_FREQUENCY,
154
+ [
155
+ Bound(
156
+ lower_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
157
+ upper_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
158
+ )
159
+ ]
160
+ )
161
+ capture_template.add_pconstraint(
162
+ PName.SAMPLE_RATE,
163
+ [
164
+ Bound(
165
+ lower_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_LOWER_BOUND),
166
+ upper_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND)
167
+ )
168
+ ]
169
+ )
170
+ capture_template.add_pconstraint(
171
+ PName.BANDWIDTH,
172
+ [
173
+ Bound(
174
+ lower_bound=usrp_receiver.get_spec(SpecName.BANDWIDTH_LOWER_BOUND),
175
+ upper_bound=usrp_receiver.get_spec(SpecName.BANDWIDTH_UPPER_BOUND),
176
+ )
177
+ ]
178
+ )
179
+ capture_template.add_pconstraint(
180
+ PName.GAIN,
181
+ [
182
+ Bound(
183
+ lower_bound=0,
184
+ upper_bound=usrp_receiver.get_spec( SpecName.GAIN_UPPER_BOUND )
185
+ )
186
+ ]
187
+ )
188
+ capture_template.add_pconstraint(
189
+ PName.WIRE_FORMAT,
190
+ [
191
+ OneOf(
192
+ usrp_receiver.get_spec( SpecName.WIRE_FORMATS )
193
+ )
194
+ ]
195
+ )
196
+ capture_template.add_pconstraint(
197
+ PName.MASTER_CLOCK_RATE,
198
+ [
199
+ Bound(
200
+ lower_bound=usrp_receiver.get_spec( SpecName.MASTER_CLOCK_RATE_LOWER_BOUND ),
201
+ upper_bound=usrp_receiver.get_spec( SpecName.MASTER_CLOCK_RATE_UPPER_BOUND )
202
+ )
203
+ ]
204
+ )
205
+ return capture_template
@@ -0,0 +1,139 @@
1
+ #
2
+ # USRP top blocks
3
+ #
4
+
5
+ from functools import partial
6
+ from dataclasses import dataclass
7
+ import time
8
+
9
+ from logging import getLogger
10
+ _LOGGER = getLogger(__name__)
11
+
12
+ from spectre_core.capture_configs import Parameters, PName
13
+ from spectre_core.config import get_batches_dir_path
14
+ from ._base import capture, spectre_top_block
15
+
16
+
17
+ class _fixed_center_frequency(spectre_top_block):
18
+ def flowgraph(
19
+ self,
20
+ tag: str,
21
+ parameters: Parameters
22
+ ) -> None:
23
+ # OOT moudle inline imports
24
+ from gnuradio import spectre
25
+ from gnuradio import uhd
26
+
27
+ # Unpack capture config parameters
28
+ sample_rate = parameters.get_parameter_value(PName.SAMPLE_RATE)
29
+ gain = parameters.get_parameter_value(PName.GAIN)
30
+ center_freq = parameters.get_parameter_value(PName.CENTER_FREQUENCY)
31
+ master_clock_rate = parameters.get_parameter_value(PName.MASTER_CLOCK_RATE)
32
+ wire_format = parameters.get_parameter_value(PName.WIRE_FORMAT)
33
+ batch_size = parameters.get_parameter_value(PName.BATCH_SIZE)
34
+ bandwidth = parameters.get_parameter_value(PName.BANDWIDTH)
35
+
36
+ # Blocks
37
+ master_clock_rate = f"master_clock_rate={master_clock_rate}"
38
+ self.uhd_usrp_source_0 = uhd.usrp_source(
39
+ ",".join(("", '', master_clock_rate)),
40
+ uhd.stream_args(
41
+ cpu_format="fc32",
42
+ otw_format=wire_format,
43
+ args='',
44
+ channels=[0],
45
+ ),
46
+ )
47
+ self.uhd_usrp_source_0.set_samp_rate(sample_rate)
48
+ self.uhd_usrp_source_0.set_time_now(uhd.time_spec(time.time()), uhd.ALL_MBOARDS)
49
+
50
+ self.uhd_usrp_source_0.set_center_freq(center_freq, 0)
51
+ self.uhd_usrp_source_0.set_antenna("RX2", 0)
52
+ self.uhd_usrp_source_0.set_bandwidth(bandwidth, 0)
53
+ self.uhd_usrp_source_0.set_rx_agc(False, 0)
54
+ self.uhd_usrp_source_0.set_auto_dc_offset(False, 0)
55
+ self.uhd_usrp_source_0.set_auto_iq_balance(False, 0)
56
+ self.uhd_usrp_source_0.set_gain(gain, 0)
57
+ self.spectre_batched_file_sink_0 = spectre.batched_file_sink(get_batches_dir_path(),
58
+ tag,
59
+ batch_size,
60
+ sample_rate, False,
61
+ 'rx_freq',
62
+ 0)
63
+
64
+
65
+ # Connections
66
+ self.connect((self.uhd_usrp_source_0, 0), (self.spectre_batched_file_sink_0, 0))
67
+
68
+
69
+ class _swept_center_frequency(spectre_top_block):
70
+ def flowgraph(
71
+ self,
72
+ tag: str,
73
+ parameters: Parameters
74
+ ) -> None:
75
+ # OOT module inline imports
76
+ from gnuradio import spectre
77
+ from gnuradio import uhd
78
+
79
+ # Unpack capture config parameters
80
+ sample_rate = parameters.get_parameter_value(PName.SAMPLE_RATE)
81
+ bandwidth = parameters.get_parameter_value(PName.BANDWIDTH)
82
+ min_frequency = parameters.get_parameter_value(PName.MIN_FREQUENCY)
83
+ max_frequency = parameters.get_parameter_value(PName.MAX_FREQUENCY)
84
+ frequency_step = parameters.get_parameter_value(PName.FREQUENCY_STEP)
85
+ samples_per_step = parameters.get_parameter_value(PName.SAMPLES_PER_STEP)
86
+ master_clock_rate = parameters.get_parameter_value(PName.MASTER_CLOCK_RATE)
87
+ master_clock_rate = master_clock_rate = parameters.get_parameter_value(PName.MASTER_CLOCK_RATE)
88
+ wire_format = parameters.get_parameter_value(PName.WIRE_FORMAT)
89
+ gain = parameters.get_parameter_value(PName.GAIN)
90
+ batch_size = parameters.get_parameter_value(PName.BATCH_SIZE)
91
+
92
+ # Blocks
93
+ _LOGGER.warning(f"USRP frequency sweep modes will not work as expected until a known bug is fixed in the USRP source block. "
94
+ f"Please refer to this GitHub issue for more information: https://github.com/gnuradio/gnuradio/issues/7725")
95
+ master_clock_rate = f"master_clock_rate={master_clock_rate}"
96
+ self.uhd_usrp_source_0 = uhd.usrp_source(
97
+ ",".join(("", '', master_clock_rate)),
98
+ uhd.stream_args(
99
+ cpu_format="fc32",
100
+ otw_format=wire_format,
101
+ args='',
102
+ channels=[0],
103
+ ),
104
+ )
105
+ self.uhd_usrp_source_0.set_samp_rate(sample_rate)
106
+ self.uhd_usrp_source_0.set_time_now(uhd.time_spec(time.time()), uhd.ALL_MBOARDS)
107
+ self.uhd_usrp_source_0.set_center_freq(min_frequency, 0)
108
+ self.uhd_usrp_source_0.set_antenna("RX2", 0)
109
+ self.uhd_usrp_source_0.set_bandwidth(bandwidth, 0)
110
+ self.uhd_usrp_source_0.set_rx_agc(False, 0)
111
+ self.uhd_usrp_source_0.set_auto_dc_offset(False, 0)
112
+ self.uhd_usrp_source_0.set_auto_iq_balance(False, 0)
113
+ self.uhd_usrp_source_0.set_gain(gain, 0)
114
+
115
+ self.spectre_sweep_driver_0 = spectre.sweep_driver(min_frequency,
116
+ max_frequency,
117
+ frequency_step,
118
+ sample_rate,
119
+ samples_per_step,
120
+ 'freq')
121
+
122
+ self.spectre_batched_file_sink_0 = spectre.batched_file_sink(get_batches_dir_path(),
123
+ tag,
124
+ batch_size,
125
+ sample_rate,
126
+ True,
127
+ 'rx_freq',
128
+ min_frequency)
129
+
130
+ # Connections
131
+ self.msg_connect((self.spectre_sweep_driver_0, 'freq'), (self.uhd_usrp_source_0, 'command'))
132
+ self.connect((self.uhd_usrp_source_0, 0), (self.spectre_batched_file_sink_0, 0))
133
+ self.connect((self.uhd_usrp_source_0, 0), (self.spectre_sweep_driver_0, 0))
134
+
135
+
136
+ @dataclass(frozen=True)
137
+ class CaptureMethod:
138
+ fixed_center_frequency = partial(capture, top_block_cls=_fixed_center_frequency)
139
+ swept_center_frequency = partial(capture, top_block_cls=_swept_center_frequency, max_noutput_items=1024)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: spectre-core
3
- Version: 0.0.15
3
+ Version: 0.0.16
4
4
  Summary: The core Python package used by the spectre program.
5
5
  Maintainer-email: Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -1,72 +0,0 @@
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
- from ._receiver_names import ReceiverName
8
- from ._usrp import (
9
- get_pvalidator_fixed_center_frequency,
10
- get_capture_template_fixed_center_frequency
11
- )
12
- from .gr._usrp import CaptureMethod
13
- from .._spec_names import SpecName
14
- from .._base import BaseReceiver
15
- from .._register import register_receiver
16
-
17
- @dataclass(frozen=True)
18
- class Mode:
19
- """An operating mode for the `B200mini` receiver."""
20
- FIXED_CENTER_FREQUENCY = "fixed_center_frequency"
21
-
22
-
23
- @register_receiver(ReceiverName.B200MINI)
24
- class B200mini(BaseReceiver):
25
- """Receiver implementation for the USRP B200mini (https://www.ettus.com/all-products/usrp-b200mini/)"""
26
- def _add_specs(
27
- self
28
- ) -> None:
29
- self.add_spec( SpecName.SAMPLE_RATE_LOWER_BOUND, 200e3 )
30
- self.add_spec( SpecName.SAMPLE_RATE_UPPER_BOUND, 56e6 )
31
- self.add_spec( SpecName.FREQUENCY_LOWER_BOUND , 70e6 )
32
- self.add_spec( SpecName.FREQUENCY_UPPER_BOUND , 6e9 )
33
- self.add_spec( SpecName.BANDWIDTH_LOWER_BOUND , 200e3 )
34
- self.add_spec( SpecName.BANDWIDTH_UPPER_BOUND , 56e6 )
35
-
36
-
37
- def _add_capture_methods(
38
- self
39
- ) -> None:
40
- self.add_capture_method(Mode.FIXED_CENTER_FREQUENCY,
41
- CaptureMethod.fixed_center_frequency)
42
-
43
-
44
- def _add_capture_templates(
45
- self
46
- ) -> None:
47
- self.add_capture_template(Mode.FIXED_CENTER_FREQUENCY,
48
- get_capture_template_fixed_center_frequency(self))
49
-
50
-
51
- def _add_pvalidators(
52
- self
53
- ) -> None:
54
- self.add_pvalidator(Mode.FIXED_CENTER_FREQUENCY,
55
- get_pvalidator_fixed_center_frequency(self))
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
@@ -1,70 +0,0 @@
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 typing import Callable, overload
6
-
7
- from spectre_core.capture_configs import (
8
- CaptureTemplate, CaptureMode, Parameters, Bound, PName,
9
- get_base_capture_template, get_base_ptemplate, OneOf,
10
- validate_fixed_center_frequency, validate_swept_center_frequency
11
- )
12
- from .._base import BaseReceiver
13
- from .._spec_names import SpecName
14
-
15
-
16
- def get_pvalidator_fixed_center_frequency(
17
- usrp_receiver: BaseReceiver
18
- ) -> Callable[[Parameters], None]:
19
- def pvalidator(parameters: Parameters) -> None:
20
- validate_fixed_center_frequency(parameters)
21
- return pvalidator
22
-
23
-
24
- def get_capture_template_fixed_center_frequency(
25
- usrp_receiver: BaseReceiver
26
- ) -> CaptureTemplate:
27
-
28
- capture_template = get_base_capture_template( CaptureMode.FIXED_CENTER_FREQUENCY )
29
- capture_template.add_ptemplate( get_base_ptemplate(PName.BANDWIDTH) )
30
- capture_template.add_ptemplate( get_base_ptemplate(PName.NORMALISED_GAIN) )
31
-
32
- capture_template.set_defaults(
33
- (PName.BATCH_SIZE, 3.0),
34
- (PName.CENTER_FREQUENCY, 95800000),
35
- (PName.SAMPLE_RATE, 1000000),
36
- (PName.BANDWIDTH, 1000000),
37
- (PName.WINDOW_HOP, 512),
38
- (PName.WINDOW_SIZE, 1024),
39
- (PName.WINDOW_TYPE, "blackman"),
40
- (PName.NORMALISED_GAIN, 0.3),
41
- )
42
-
43
- capture_template.add_pconstraint(
44
- PName.CENTER_FREQUENCY,
45
- [
46
- Bound(
47
- lower_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
48
- upper_bound=usrp_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
49
- )
50
- ]
51
- )
52
- capture_template.add_pconstraint(
53
- PName.SAMPLE_RATE,
54
- [
55
- Bound(
56
- lower_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_LOWER_BOUND),
57
- upper_bound=usrp_receiver.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND)
58
- )
59
- ]
60
- )
61
- capture_template.add_pconstraint(
62
- PName.BANDWIDTH,
63
- [
64
- Bound(
65
- lower_bound=usrp_receiver.get_spec( SpecName.BANDWIDTH_LOWER_BOUND ),
66
- upper_bound=usrp_receiver.get_spec( SpecName.BANDWIDTH_UPPER_BOUND )
67
- )
68
- ]
69
- )
70
- return capture_template
@@ -1,62 +0,0 @@
1
- #
2
- # USRP top blocks
3
- #
4
-
5
- from functools import partial
6
- from dataclasses import dataclass
7
- import time
8
-
9
- from spectre_core.capture_configs import Parameters, PName
10
- from spectre_core.config import get_batches_dir_path
11
- from ._base import capture, spectre_top_block
12
-
13
-
14
- class _fixed_center_frequency(spectre_top_block):
15
- def flowgraph(
16
- self,
17
- tag: str,
18
- parameters: Parameters
19
- ) -> None:
20
- # OOT moudle inline imports
21
- from gnuradio import spectre
22
- from gnuradio import uhd
23
-
24
- # Variables
25
- sample_rate = parameters.get_parameter_value(PName.SAMPLE_RATE)
26
- normalised_gain = parameters.get_parameter_value(PName.NORMALISED_GAIN)
27
- center_freq = parameters.get_parameter_value(PName.CENTER_FREQUENCY)
28
- batch_size = parameters.get_parameter_value(PName.BATCH_SIZE)
29
- bandwidth = parameters.get_parameter_value(PName.BANDWIDTH)
30
-
31
- # Blocks
32
- self.uhd_usrp_source_0 = uhd.usrp_source(
33
- ",".join(("", '')),
34
- uhd.stream_args(
35
- cpu_format="fc32",
36
- args='',
37
- channels=list(range(0,1)),
38
- ),
39
- )
40
- self.uhd_usrp_source_0.set_samp_rate(sample_rate)
41
- self.uhd_usrp_source_0.set_time_now(uhd.time_spec(time.time()), uhd.ALL_MBOARDS)
42
-
43
- self.uhd_usrp_source_0.set_center_freq(center_freq, 0)
44
- self.uhd_usrp_source_0.set_antenna("RX2", 0)
45
- self.uhd_usrp_source_0.set_bandwidth(bandwidth, 0)
46
- self.uhd_usrp_source_0.set_rx_agc(False, 0)
47
- self.uhd_usrp_source_0.set_normalized_gain(normalised_gain, 0)
48
- self.spectre_batched_file_sink_0 = spectre.batched_file_sink(get_batches_dir_path(),
49
- tag,
50
- batch_size,
51
- sample_rate, False,
52
- 'freq',
53
- 0)
54
-
55
-
56
- # Connections
57
- self.connect((self.uhd_usrp_source_0, 0), (self.spectre_batched_file_sink_0, 0))
58
-
59
-
60
- @dataclass(frozen=True)
61
- class CaptureMethod:
62
- fixed_center_frequency = partial(capture, top_block_cls=_fixed_center_frequency)
File without changes
File without changes
File without changes