spectre-core 0.0.14__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 (85) hide show
  1. {spectre_core-0.0.14 → spectre_core-0.0.16}/PKG-INFO +1 -1
  2. {spectre_core-0.0.14 → spectre_core-0.0.16}/pyproject.toml +1 -1
  3. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/capture_configs/__init__.py +3 -3
  4. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_pnames.py +4 -1
  5. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_ptemplates.py +20 -2
  6. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_pvalidators.py +16 -0
  7. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/receivers/__init__.py +3 -2
  8. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/receivers/_base.py +4 -27
  9. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/receivers/_factory.py +9 -0
  10. spectre_core-0.0.16/src/spectre_core/receivers/_spec_names.py +41 -0
  11. spectre_core-0.0.16/src/spectre_core/receivers/plugins/_b200mini.py +84 -0
  12. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/_receiver_names.py +5 -3
  13. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/_rsp1a.py +13 -7
  14. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/_rspduo.py +12 -8
  15. spectre_core-0.0.16/src/spectre_core/receivers/plugins/_sdrplay_receiver.py +174 -0
  16. spectre_core-0.0.16/src/spectre_core/receivers/plugins/_usrp.py +205 -0
  17. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/gr/_rsp1a.py +1 -15
  18. spectre_core-0.0.16/src/spectre_core/receivers/plugins/gr/_usrp.py +139 -0
  19. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core.egg-info/PKG-INFO +1 -1
  20. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core.egg-info/SOURCES.txt +3 -0
  21. spectre_core-0.0.14/src/spectre_core/receivers/_spec_names.py +0 -31
  22. spectre_core-0.0.14/src/spectre_core/receivers/plugins/_sdrplay_receiver.py +0 -190
  23. {spectre_core-0.0.14 → spectre_core-0.0.16}/LICENSE +0 -0
  24. {spectre_core-0.0.14 → spectre_core-0.0.16}/README.md +0 -0
  25. {spectre_core-0.0.14 → spectre_core-0.0.16}/setup.cfg +0 -0
  26. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/__init__.py +0 -0
  27. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/_file_io/__init__.py +0 -0
  28. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/_file_io/file_handlers.py +0 -0
  29. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/batches/__init__.py +0 -0
  30. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/batches/_base.py +0 -0
  31. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/batches/_batches.py +0 -0
  32. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/batches/_factory.py +0 -0
  33. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/batches/_register.py +0 -0
  34. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/batches/plugins/_batch_keys.py +0 -0
  35. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/batches/plugins/_callisto.py +0 -0
  36. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/batches/plugins/_iq_stream.py +0 -0
  37. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_capture_config.py +0 -0
  38. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_capture_modes.py +0 -0
  39. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_capture_templates.py +0 -0
  40. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_parameters.py +0 -0
  41. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/capture_configs/_pconstraints.py +0 -0
  42. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/config/__init__.py +0 -0
  43. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/config/_paths.py +0 -0
  44. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/config/_time_formats.py +0 -0
  45. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/exceptions.py +0 -0
  46. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/jobs/__init__.py +0 -0
  47. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/jobs/_jobs.py +0 -0
  48. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/jobs/_workers.py +0 -0
  49. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/logs/__init__.py +0 -0
  50. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/logs/_configure.py +0 -0
  51. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/logs/_decorators.py +0 -0
  52. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/logs/_logs.py +0 -0
  53. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/logs/_process_types.py +0 -0
  54. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/plotting/__init__.py +0 -0
  55. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/plotting/_base.py +0 -0
  56. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/plotting/_format.py +0 -0
  57. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/plotting/_panel_names.py +0 -0
  58. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/plotting/_panel_stack.py +0 -0
  59. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/plotting/_panels.py +0 -0
  60. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/post_processing/__init__.py +0 -0
  61. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/post_processing/_base.py +0 -0
  62. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/post_processing/_factory.py +0 -0
  63. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/post_processing/_post_processor.py +0 -0
  64. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/post_processing/_register.py +0 -0
  65. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/post_processing/plugins/_event_handler_keys.py +0 -0
  66. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/post_processing/plugins/_fixed_center_frequency.py +0 -0
  67. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/post_processing/plugins/_swept_center_frequency.py +0 -0
  68. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/py.typed +0 -0
  69. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/receivers/_register.py +0 -0
  70. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/__init__.py +0 -0
  71. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/_test.py +0 -0
  72. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/gr/__init__.py +0 -0
  73. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/gr/_base.py +0 -0
  74. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/gr/_rspduo.py +0 -0
  75. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/receivers/plugins/gr/_test.py +0 -0
  76. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/spectrograms/__init__.py +0 -0
  77. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/spectrograms/_analytical.py +0 -0
  78. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/spectrograms/_array_operations.py +0 -0
  79. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/spectrograms/_spectrogram.py +0 -0
  80. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/spectrograms/_transform.py +0 -0
  81. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/wgetting/__init__.py +0 -0
  82. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core/wgetting/_callisto.py +0 -0
  83. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core.egg-info/dependency_links.txt +0 -0
  84. {spectre_core-0.0.14 → spectre_core-0.0.16}/src/spectre_core.egg-info/requires.txt +0 -0
  85. {spectre_core-0.0.14 → 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.14
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.14"
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
+ ]
@@ -46,4 +46,7 @@ class PName(Enum):
46
46
  OBJECT = "object"
47
47
  OBS_LAT = "obs_lat"
48
48
  OBS_LON = "obs_lon"
49
- OBS_ALT = "obs_alt"
49
+ OBS_ALT = "obs_alt"
50
+ GAIN = "gain"
51
+ MASTER_CLOCK_RATE = "master_clock_rate"
52
+ WIRE_FORMAT = "wire_format"
@@ -7,7 +7,7 @@ from textwrap import dedent
7
7
  from copy import deepcopy
8
8
 
9
9
  from ._pnames import PName
10
- from ._pconstraints import BasePConstraint, EnforceSign, PowerOfTwo
10
+ from ._pconstraints import BasePConstraint, EnforceSign, PowerOfTwo, Bound
11
11
  from ._parameters import Parameter
12
12
 
13
13
  # value type
@@ -300,6 +300,24 @@ _base_ptemplates: dict[PName, PTemplate] = {
300
300
  pconstraints=[
301
301
  EnforceSign.non_positive
302
302
  ]),
303
+ PName.GAIN: PTemplate(PName.GAIN,
304
+ float,
305
+ help = """
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
+ ),
303
321
  PName.EVENT_HANDLER_KEY: PTemplate(PName.EVENT_HANDLER_KEY,
304
322
  str,
305
323
  help = """
@@ -490,4 +508,4 @@ def get_base_ptemplate(
490
508
  # A deep copy is required as each receiver instance may mutate the original instance
491
509
  # according to its particular use case. Copying preserves the original instance,
492
510
  # enabling reuse.
493
- return deepcopy( _base_ptemplates[pname] )
511
+ return deepcopy( _base_ptemplates[pname] )
@@ -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:
@@ -8,6 +8,7 @@ from .plugins._receiver_names import ReceiverName
8
8
  from .plugins._test import Test
9
9
  from .plugins._rsp1a import RSP1A
10
10
  from .plugins._rspduo import RSPduo
11
+ from .plugins._b200mini import B200mini
11
12
 
12
13
  from ._base import BaseReceiver
13
14
  from ._factory import get_receiver
@@ -15,6 +16,6 @@ from ._register import get_registered_receivers
15
16
  from ._spec_names import SpecName
16
17
 
17
18
  __all__ = [
18
- "Test", "RSP1A", "RSPduo", "BaseReceiver", "get_receiver",
19
+ "Test", "RSP1A", "RSPduo", "B200mini", "BaseReceiver", "get_receiver",
19
20
  "get_registered_receivers", "SpecName", "ReceiverName"
20
- ]
21
+ ]
@@ -3,7 +3,7 @@
3
3
  # SPDX-License-Identifier: GPL-3.0-or-later
4
4
 
5
5
  from abc import ABC, abstractmethod
6
- from typing import Callable, Optional, Literal, overload
6
+ from typing import Callable, Optional, Literal, overload, Any
7
7
 
8
8
  from spectre_core.exceptions import ModeNotFoundError
9
9
  from spectre_core.capture_configs import (
@@ -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.
@@ -236,34 +236,11 @@ class BaseReceiver(ABC):
236
236
  """
237
237
  self.specs[name] = value
238
238
 
239
-
240
- # tell static type checkers the type of specification
241
- @overload
242
- def get_spec(self, spec_name: Literal[SpecName.API_RETUNING_LATENCY]) -> float: ...
243
- @overload
244
- def get_spec(self, spec_name: Literal[SpecName.FREQUENCY_LOWER_BOUND]) -> float: ...
245
- @overload
246
- def get_spec(self, spec_name: Literal[SpecName.FREQUENCY_UPPER_BOUND]) -> float: ...
247
- @overload
248
- def get_spec(self, spec_name: Literal[SpecName.SAMPLE_RATE_LOWER_BOUND]) -> int: ...
249
- @overload
250
- def get_spec(self, spec_name: Literal[SpecName.SAMPLE_RATE_UPPER_BOUND]) -> int: ...
251
- @overload
252
- def get_spec(self, spec_name: Literal[SpecName.BANDWIDTH_LOWER_BOUND]) -> float: ...
253
- @overload
254
- def get_spec(self, spec_name: Literal[SpecName.BANDWIDTH_UPPER_BOUND]) -> float: ...
255
- @overload
256
- def get_spec(self, spec_name: Literal[SpecName.RF_GAIN_UPPER_BOUND]) -> int: ...
257
- @overload
258
- def get_spec(self, spec_name: Literal[SpecName.IF_GAIN_UPPER_BOUND]) -> int: ...
259
- @overload
260
- def get_spec(self, spec_name: Literal[SpecName.BANDWIDTH_OPTIONS]) -> list[float]: ...
261
-
262
239
 
263
240
  def get_spec(
264
241
  self,
265
242
  spec_name: SpecName
266
- ) -> float|int|list[float|int]:
243
+ ) -> Any:
267
244
  """
268
245
  Retrieve a hardware specification.
269
246
 
@@ -328,4 +305,4 @@ class BaseReceiver(ABC):
328
305
  parameters = self.capture_template.apply_template(capture_config.parameters)
329
306
  self.pvalidator(parameters)
330
307
 
331
- return parameters
308
+ return parameters
@@ -11,6 +11,7 @@ from .plugins._receiver_names import ReceiverName
11
11
  from .plugins._rsp1a import RSP1A
12
12
  from .plugins._rspduo import RSPduo
13
13
  from .plugins._test import Test
14
+ from .plugins._b200mini import B200mini
14
15
 
15
16
 
16
17
  @overload
@@ -37,6 +38,14 @@ def get_receiver(
37
38
  ...
38
39
 
39
40
 
41
+ @overload
42
+ def get_receiver(
43
+ receiver_name: Literal[ReceiverName.B200MINI],
44
+ mode: Optional[str] = None
45
+ ) -> B200mini:
46
+ ...
47
+
48
+
40
49
  @overload
41
50
  def get_receiver(
42
51
  receiver_name: ReceiverName,
@@ -0,0 +1,41 @@
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 enum import Enum
6
+
7
+ class SpecName(Enum):
8
+ """A hardware specification name.
9
+
10
+ :ivar FREQUENCY_LOWER_BOUND: The lower bound for the center frequency, in Hz.
11
+ :ivar FREQUENCY_UPPER_BOUND: The upper bound for the center frequency, in Hz.
12
+ :ivar SAMPLE_RATE_LOWER_BOUND: The lower bound for the sampling rate, in Hz.
13
+ :ivar SAMPLE_RATE_UPPER_BOUND: The upper bound for the sampling rate, in Hz.
14
+ :ivar BANDWIDTH_LOWER_BOUND: The lower bound for the bandwidth, in Hz.
15
+ :ivar BANDWIDTH_UPPER_BOUND: The upper bound for the bandwidth, in Hz.
16
+ :ivar BANDWIDTH_OPTIONS: The permitted bandwidths for the receiver, in Hz.
17
+ :ivar IF_GAIN_UPPER_BOUND: The upper bound for the intermediate frequency gain, in dB.
18
+ Negative values indicate attenuation.
19
+ :ivar RF_GAIN_UPPER_BOUND: The upper bound for the radio frequency gain, in dB.
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.
25
+ :ivar API_RETUNING_LATENCY: An empirical estimate of the delay between issuing a command
26
+ for a receiver to retune its center frequency and the actual physical update of the center frequency.
27
+ """
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
+
@@ -10,7 +10,9 @@ class ReceiverName(Enum):
10
10
  :ivar RSP1A: SDRPlay RSP1A
11
11
  :ivar RSPDUO: SDRPlay RSPduo
12
12
  :ivar TEST: `spectre` test receiver.
13
+ :ivar B200MINI: USRP B200mini.
13
14
  """
14
- RSP1A = "rsp1a"
15
- RSPDUO = "rspduo"
16
- TEST = "test"
15
+ RSP1A = "rsp1a"
16
+ RSPDUO = "rspduo"
17
+ TEST = "test"
18
+ B200MINI = "b200mini"
@@ -6,8 +6,12 @@ from dataclasses import dataclass
6
6
 
7
7
  from ._receiver_names import ReceiverName
8
8
  from .gr._rsp1a import CaptureMethod
9
+ from ._sdrplay_receiver import (
10
+ get_pvalidator_fixed_center_frequency, get_pvalidator_swept_center_frequency,
11
+ get_capture_template_fixed_center_frequency, get_capture_template_swept_center_frequency
12
+ )
9
13
  from .._spec_names import SpecName
10
- from ._sdrplay_receiver import SDRPlayReceiver
14
+ from .._base import BaseReceiver
11
15
  from .._register import register_receiver
12
16
 
13
17
  @dataclass(frozen=True)
@@ -18,9 +22,11 @@ class Mode:
18
22
 
19
23
 
20
24
  @register_receiver(ReceiverName.RSP1A)
21
- class RSP1A(SDRPlayReceiver):
25
+ class RSP1A(BaseReceiver):
22
26
  """Receiver implementation for the SDRPlay RSP1A (https://www.sdrplay.com/rsp1a/)"""
23
- def _add_specs(self) -> None:
27
+ def _add_specs(
28
+ self
29
+ ) -> None:
24
30
  self.add_spec( SpecName.SAMPLE_RATE_LOWER_BOUND, 200e3 )
25
31
  self.add_spec( SpecName.SAMPLE_RATE_UPPER_BOUND, 10e6 )
26
32
  self.add_spec( SpecName.FREQUENCY_LOWER_BOUND , 1e3 )
@@ -45,15 +51,15 @@ class RSP1A(SDRPlayReceiver):
45
51
  self
46
52
  ) -> None:
47
53
  self.add_capture_template(Mode.FIXED_CENTER_FREQUENCY,
48
- self._get_capture_template_fixed_center_frequency())
54
+ get_capture_template_fixed_center_frequency(self))
49
55
  self.add_capture_template(Mode.SWEPT_CENTER_FREQUENCY,
50
- self._get_capture_template_swept_center_frequency())
56
+ get_capture_template_swept_center_frequency(self))
51
57
 
52
58
 
53
59
  def _add_pvalidators(
54
60
  self
55
61
  ) -> None:
56
62
  self.add_pvalidator(Mode.FIXED_CENTER_FREQUENCY,
57
- self._get_pvalidator_fixed_center_frequency())
63
+ get_pvalidator_fixed_center_frequency(self))
58
64
  self.add_pvalidator(Mode.SWEPT_CENTER_FREQUENCY,
59
- self._get_pvalidator_swept_center_frequency())
65
+ get_pvalidator_swept_center_frequency(self))
@@ -7,7 +7,11 @@ from dataclasses import dataclass
7
7
  from ._receiver_names import ReceiverName
8
8
  from .gr._rspduo import CaptureMethod
9
9
  from .._spec_names import SpecName
10
- from ._sdrplay_receiver import SDRPlayReceiver
10
+ from ._sdrplay_receiver import (
11
+ get_pvalidator_fixed_center_frequency, get_pvalidator_swept_center_frequency,
12
+ get_capture_template_fixed_center_frequency, get_capture_template_swept_center_frequency
13
+ )
14
+ from .._base import BaseReceiver
11
15
  from .._register import register_receiver
12
16
 
13
17
 
@@ -20,7 +24,7 @@ class Mode:
20
24
 
21
25
 
22
26
  @register_receiver(ReceiverName.RSPDUO)
23
- class RSPduo(SDRPlayReceiver):
27
+ class RSPduo(BaseReceiver):
24
28
  """Receiver implementation for the SDRPlay RSPduo (https://www.sdrplay.com/rspduo/)"""
25
29
  def _add_specs(self) -> None:
26
30
  self.add_spec( SpecName.SAMPLE_RATE_LOWER_BOUND, 200e3 )
@@ -49,19 +53,19 @@ class RSPduo(SDRPlayReceiver):
49
53
  self
50
54
  ) -> None:
51
55
  self.add_capture_template(Mode.TUNER_1_FIXED_CENTER_FREQUENCY,
52
- self._get_capture_template_fixed_center_frequency())
56
+ get_capture_template_fixed_center_frequency(self))
53
57
  self.add_capture_template(Mode.TUNER_2_FIXED_CENTER_FREQUENCY,
54
- self._get_capture_template_fixed_center_frequency())
58
+ get_capture_template_fixed_center_frequency(self))
55
59
  self.add_capture_template(Mode.TUNER_1_SWEPT_CENTER_FREQUENCY,
56
- self._get_capture_template_swept_center_frequency())
60
+ get_capture_template_swept_center_frequency(self))
57
61
 
58
62
 
59
63
  def _add_pvalidators(
60
64
  self
61
65
  ) -> None:
62
66
  self.add_pvalidator(Mode.TUNER_1_FIXED_CENTER_FREQUENCY,
63
- self._get_pvalidator_fixed_center_frequency())
67
+ get_pvalidator_fixed_center_frequency(self))
64
68
  self.add_pvalidator(Mode.TUNER_2_FIXED_CENTER_FREQUENCY,
65
- self._get_pvalidator_fixed_center_frequency())
69
+ get_pvalidator_fixed_center_frequency(self))
66
70
  self.add_pvalidator(Mode.TUNER_1_SWEPT_CENTER_FREQUENCY,
67
- self._get_pvalidator_swept_center_frequency())
71
+ get_pvalidator_swept_center_frequency(self))
@@ -0,0 +1,174 @@
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
+ sdrplay_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_pvalidator_swept_center_frequency(
25
+ sdrplay_receiver: BaseReceiver
26
+ ) -> Callable[[Parameters], None]:
27
+ def pvalidator(parameters: Parameters) -> None:
28
+ validate_swept_center_frequency(parameters,
29
+ sdrplay_receiver.get_spec(SpecName.API_RETUNING_LATENCY))
30
+ return pvalidator
31
+
32
+
33
+ def get_capture_template_fixed_center_frequency(
34
+ sdrplay_receiver: BaseReceiver
35
+ ) -> CaptureTemplate:
36
+
37
+ capture_template = get_base_capture_template( CaptureMode.FIXED_CENTER_FREQUENCY )
38
+ capture_template.add_ptemplate( get_base_ptemplate(PName.BANDWIDTH) )
39
+ capture_template.add_ptemplate( get_base_ptemplate(PName.IF_GAIN) )
40
+ capture_template.add_ptemplate( get_base_ptemplate(PName.RF_GAIN) )
41
+
42
+ capture_template.set_defaults(
43
+ (PName.BATCH_SIZE, 3.0),
44
+ (PName.CENTER_FREQUENCY, 95800000),
45
+ (PName.SAMPLE_RATE, 600000),
46
+ (PName.BANDWIDTH, 600000),
47
+ (PName.WINDOW_HOP, 512),
48
+ (PName.WINDOW_SIZE, 1024),
49
+ (PName.WINDOW_TYPE, "blackman"),
50
+ (PName.RF_GAIN, -30),
51
+ (PName.IF_GAIN, -30)
52
+ )
53
+
54
+ capture_template.add_pconstraint(
55
+ PName.CENTER_FREQUENCY,
56
+ [
57
+ Bound(
58
+ lower_bound=sdrplay_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
59
+ upper_bound=sdrplay_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
60
+ )
61
+ ]
62
+ )
63
+ capture_template.add_pconstraint(
64
+ PName.SAMPLE_RATE,
65
+ [
66
+ Bound(
67
+ lower_bound=sdrplay_receiver.get_spec(SpecName.SAMPLE_RATE_LOWER_BOUND),
68
+ upper_bound=sdrplay_receiver.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND)
69
+ )
70
+ ]
71
+ )
72
+ capture_template.add_pconstraint(
73
+ PName.BANDWIDTH,
74
+ [
75
+ OneOf(
76
+ sdrplay_receiver.get_spec( SpecName.BANDWIDTH_OPTIONS )
77
+ )
78
+ ]
79
+ )
80
+ capture_template.add_pconstraint(
81
+ PName.IF_GAIN,
82
+ [
83
+ Bound(
84
+ upper_bound=sdrplay_receiver.get_spec(SpecName.IF_GAIN_UPPER_BOUND)
85
+ )
86
+ ]
87
+ )
88
+ capture_template.add_pconstraint(
89
+ PName.RF_GAIN,
90
+ [
91
+ Bound(
92
+ upper_bound=sdrplay_receiver.get_spec(SpecName.RF_GAIN_UPPER_BOUND)
93
+ )
94
+ ]
95
+ )
96
+ return capture_template
97
+
98
+
99
+ def get_capture_template_swept_center_frequency(
100
+ sdrplay_receiver: BaseReceiver
101
+ ) -> CaptureTemplate:
102
+
103
+ capture_template = get_base_capture_template( CaptureMode.SWEPT_CENTER_FREQUENCY )
104
+ capture_template.add_ptemplate( get_base_ptemplate(PName.BANDWIDTH) )
105
+ capture_template.add_ptemplate( get_base_ptemplate(PName.IF_GAIN) )
106
+ capture_template.add_ptemplate( get_base_ptemplate(PName.RF_GAIN) )
107
+
108
+ capture_template.set_defaults(
109
+ (PName.BATCH_SIZE, 4.0),
110
+ (PName.MIN_FREQUENCY, 95000000),
111
+ (PName.MAX_FREQUENCY, 100000000),
112
+ (PName.SAMPLES_PER_STEP, 80000),
113
+ (PName.FREQUENCY_STEP, 1536000),
114
+ (PName.SAMPLE_RATE, 1536000),
115
+ (PName.BANDWIDTH, 1536000),
116
+ (PName.WINDOW_HOP, 512),
117
+ (PName.WINDOW_SIZE, 1024),
118
+ (PName.WINDOW_TYPE, "blackman"),
119
+ (PName.RF_GAIN, -30),
120
+ (PName.IF_GAIN, -30)
121
+ )
122
+
123
+ capture_template.add_pconstraint(
124
+ PName.MIN_FREQUENCY,
125
+ [
126
+ Bound(
127
+ lower_bound=sdrplay_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
128
+ upper_bound=sdrplay_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
129
+ )
130
+ ]
131
+ )
132
+ capture_template.add_pconstraint(
133
+ PName.MAX_FREQUENCY,
134
+ [
135
+ Bound(
136
+ lower_bound=sdrplay_receiver.get_spec(SpecName.FREQUENCY_LOWER_BOUND),
137
+ upper_bound=sdrplay_receiver.get_spec(SpecName.FREQUENCY_UPPER_BOUND)
138
+ )
139
+ ]
140
+ )
141
+ capture_template.add_pconstraint(
142
+ PName.SAMPLE_RATE,
143
+ [
144
+ Bound(
145
+ lower_bound=sdrplay_receiver.get_spec(SpecName.SAMPLE_RATE_LOWER_BOUND),
146
+ upper_bound=sdrplay_receiver.get_spec(SpecName.SAMPLE_RATE_UPPER_BOUND)
147
+ )
148
+ ]
149
+ )
150
+ capture_template.add_pconstraint(
151
+ PName.BANDWIDTH,
152
+ [
153
+ OneOf(
154
+ sdrplay_receiver.get_spec( SpecName.BANDWIDTH_OPTIONS )
155
+ )
156
+ ]
157
+ )
158
+ capture_template.add_pconstraint(
159
+ PName.IF_GAIN,
160
+ [
161
+ Bound(
162
+ upper_bound=sdrplay_receiver.get_spec(SpecName.IF_GAIN_UPPER_BOUND)
163
+ )
164
+ ]
165
+ )
166
+ capture_template.add_pconstraint(
167
+ PName.RF_GAIN,
168
+ [
169
+ Bound(
170
+ upper_bound=sdrplay_receiver.get_spec(SpecName.RF_GAIN_UPPER_BOUND)
171
+ )
172
+ ]
173
+ )
174
+ return capture_template