spectre-core 0.0.15__tar.gz → 0.0.17__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.17}/PKG-INFO +1 -1
  2. {spectre_core-0.0.15 → spectre_core-0.0.17}/pyproject.toml +1 -1
  3. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/capture_configs/__init__.py +3 -3
  4. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/capture_configs/_pnames.py +3 -1
  5. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/capture_configs/_ptemplates.py +16 -6
  6. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/capture_configs/_pvalidators.py +16 -0
  7. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/config/__init__.py +3 -2
  8. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/config/_paths.py +32 -0
  9. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/_base.py +1 -1
  10. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/_spec_names.py +18 -10
  11. spectre_core-0.0.17/src/spectre_core/receivers/plugins/_b200mini.py +84 -0
  12. spectre_core-0.0.17/src/spectre_core/receivers/plugins/_usrp.py +205 -0
  13. spectre_core-0.0.17/src/spectre_core/receivers/plugins/gr/_usrp.py +139 -0
  14. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/wgetting/_callisto.py +16 -7
  15. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core.egg-info/PKG-INFO +1 -1
  16. spectre_core-0.0.15/src/spectre_core/receivers/plugins/_b200mini.py +0 -72
  17. spectre_core-0.0.15/src/spectre_core/receivers/plugins/_usrp.py +0 -70
  18. spectre_core-0.0.15/src/spectre_core/receivers/plugins/gr/_usrp.py +0 -62
  19. {spectre_core-0.0.15 → spectre_core-0.0.17}/LICENSE +0 -0
  20. {spectre_core-0.0.15 → spectre_core-0.0.17}/README.md +0 -0
  21. {spectre_core-0.0.15 → spectre_core-0.0.17}/setup.cfg +0 -0
  22. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/__init__.py +0 -0
  23. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/_file_io/__init__.py +0 -0
  24. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/_file_io/file_handlers.py +0 -0
  25. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/batches/__init__.py +0 -0
  26. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/batches/_base.py +0 -0
  27. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/batches/_batches.py +0 -0
  28. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/batches/_factory.py +0 -0
  29. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/batches/_register.py +0 -0
  30. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/batches/plugins/_batch_keys.py +0 -0
  31. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/batches/plugins/_callisto.py +0 -0
  32. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/batches/plugins/_iq_stream.py +0 -0
  33. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/capture_configs/_capture_config.py +0 -0
  34. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/capture_configs/_capture_modes.py +0 -0
  35. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/capture_configs/_capture_templates.py +0 -0
  36. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/capture_configs/_parameters.py +0 -0
  37. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/capture_configs/_pconstraints.py +0 -0
  38. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/config/_time_formats.py +0 -0
  39. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/exceptions.py +0 -0
  40. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/jobs/__init__.py +0 -0
  41. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/jobs/_jobs.py +0 -0
  42. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/jobs/_workers.py +0 -0
  43. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/logs/__init__.py +0 -0
  44. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/logs/_configure.py +0 -0
  45. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/logs/_decorators.py +0 -0
  46. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/logs/_logs.py +0 -0
  47. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/logs/_process_types.py +0 -0
  48. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/plotting/__init__.py +0 -0
  49. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/plotting/_base.py +0 -0
  50. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/plotting/_format.py +0 -0
  51. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/plotting/_panel_names.py +0 -0
  52. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/plotting/_panel_stack.py +0 -0
  53. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/plotting/_panels.py +0 -0
  54. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/post_processing/__init__.py +0 -0
  55. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/post_processing/_base.py +0 -0
  56. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/post_processing/_factory.py +0 -0
  57. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/post_processing/_post_processor.py +0 -0
  58. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/post_processing/_register.py +0 -0
  59. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/post_processing/plugins/_event_handler_keys.py +0 -0
  60. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/post_processing/plugins/_fixed_center_frequency.py +0 -0
  61. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/post_processing/plugins/_swept_center_frequency.py +0 -0
  62. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/py.typed +0 -0
  63. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/__init__.py +0 -0
  64. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/_factory.py +0 -0
  65. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/_register.py +0 -0
  66. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/plugins/__init__.py +0 -0
  67. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/plugins/_receiver_names.py +0 -0
  68. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/plugins/_rsp1a.py +0 -0
  69. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/plugins/_rspduo.py +0 -0
  70. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/plugins/_sdrplay_receiver.py +0 -0
  71. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/plugins/_test.py +0 -0
  72. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/plugins/gr/__init__.py +0 -0
  73. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/plugins/gr/_base.py +0 -0
  74. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/plugins/gr/_rsp1a.py +0 -0
  75. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/plugins/gr/_rspduo.py +0 -0
  76. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/receivers/plugins/gr/_test.py +0 -0
  77. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/spectrograms/__init__.py +0 -0
  78. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/spectrograms/_analytical.py +0 -0
  79. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/spectrograms/_array_operations.py +0 -0
  80. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/spectrograms/_spectrogram.py +0 -0
  81. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/spectrograms/_transform.py +0 -0
  82. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core/wgetting/__init__.py +0 -0
  83. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core.egg-info/SOURCES.txt +0 -0
  84. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core.egg-info/dependency_links.txt +0 -0
  85. {spectre_core-0.0.15 → spectre_core-0.0.17}/src/spectre_core.egg-info/requires.txt +0 -0
  86. {spectre_core-0.0.15 → spectre_core-0.0.17}/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.17
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.17"
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:
@@ -6,7 +6,8 @@
6
6
  """General `spectre` package configurations."""
7
7
 
8
8
  from ._paths import (
9
- get_spectre_data_dir_path, get_batches_dir_path, get_configs_dir_path, get_logs_dir_path
9
+ get_spectre_data_dir_path, get_batches_dir_path, get_configs_dir_path,
10
+ get_logs_dir_path, trim_spectre_data_dir_path
10
11
  )
11
12
  from ._time_formats import (
12
13
  TimeFormat
@@ -14,5 +15,5 @@ from ._time_formats import (
14
15
 
15
16
  __all__ = [
16
17
  "get_spectre_data_dir_path", "get_batches_dir_path", "get_configs_dir_path", "get_logs_dir_path",
17
- "TimeFormat"
18
+ "TimeFormat", "trim_spectre_data_dir_path"
18
19
  ]
@@ -115,3 +115,35 @@ def get_configs_dir_path(
115
115
  :return: The directory path for configuration files.
116
116
  """
117
117
  return _CONFIGS_DIR_PATH
118
+
119
+
120
+ def trim_spectre_data_dir_path(
121
+ full_path: str
122
+ ) -> str:
123
+ """Remove the `SPECTRE_DATA_DIR_PATH` prefix from a full file path.
124
+
125
+ This function returns the relative path of `full_path` with respect to
126
+ `SPECTRE_DATA_DIR_PATH`. It is useful for trimming absolute paths
127
+ to maintain consistency across different environments where the base
128
+ directory might differ.
129
+
130
+ :param full_path: The full file path to be trimmed.
131
+ :return: The relative path with `SPECTRE_DATA_DIR_PATH` removed.
132
+ """
133
+ return os.path.relpath(full_path, _SPECTRE_DATA_DIR_PATH)
134
+
135
+
136
+ def add_spectre_data_dir_path(
137
+ rel_path: str
138
+ ) -> str:
139
+ """Prepend the `SPECTRE_DATA_DIR_PATH` prefix to a relative file path.
140
+
141
+ This function constructs an absolute path by joining the given relative
142
+ path with `SPECTRE_DATA_DIR_PATH`. It is useful for converting stored
143
+ relative paths back into full paths within the mounted directory.
144
+
145
+ :param rel_path: The relative file path to be appended.
146
+ :return: The full file path prefixed with `SPECTRE_DATA_DIR_PATH`.
147
+ """
148
+ return os.path.join(_SPECTRE_DATA_DIR_PATH, rel_path)
149
+
@@ -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)
@@ -8,7 +8,9 @@ import shutil
8
8
  import gzip
9
9
  from datetime import datetime
10
10
 
11
- from spectre_core.config import get_spectre_data_dir_path, get_batches_dir_path, TimeFormat
11
+ from spectre_core.config import (
12
+ get_spectre_data_dir_path, get_batches_dir_path, TimeFormat, trim_spectre_data_dir_path
13
+ )
12
14
 
13
15
  from enum import Enum
14
16
 
@@ -129,30 +131,37 @@ def _get_batch_path(
129
131
 
130
132
  def _unzip_file_to_batches(
131
133
  gz_path: str
132
- ) -> None:
134
+ ) -> str:
133
135
  """
134
136
  Decompress a `.fit.gz` file and save it as a `.fits` batch file.
135
137
 
136
138
  :param gz_path: Path to the `.fit.gz` file.
139
+ :return: The file path of the newly created batch file, relative to `SPECTRE_DATA_DIR_PATH`.
137
140
  """
138
141
  fits_path = _get_batch_path(gz_path)
139
142
  with gzip.open(gz_path, "rb") as f_in, open(fits_path, "wb") as f_out:
140
143
  shutil.copyfileobj(f_in, f_out)
144
+ return trim_spectre_data_dir_path(f_out.name)
141
145
 
142
146
 
143
147
  def _unzip_to_batches(
144
148
  tmp_dir: str
145
- ) -> None:
149
+ ) -> list[str]:
146
150
  """
147
151
  Decompress all `.gz` files in a temporary directory and save them as `spectre`
148
152
  batch files.
149
153
 
150
154
  :param tmp_dir: Path to the temporary directory containing `.gz` files.
155
+ :return: A list of file names of all newly created batch files, relative to `SPECTRE_DATA_DIR_PATH`.
151
156
  """
157
+ batch_file_names = []
152
158
  for entry in os.scandir(tmp_dir):
153
159
  if entry.is_file() and entry.name.endswith(".gz"):
154
- _unzip_file_to_batches(entry.path)
160
+ batch_file_names.append( _unzip_file_to_batches(entry.path) )
155
161
  os.remove(entry.path)
162
+ shutil.rmtree(tmp_dir)
163
+ return batch_file_names
164
+
156
165
 
157
166
 
158
167
  def _wget_callisto_data(
@@ -186,7 +195,7 @@ def download_callisto_data(
186
195
  year: int,
187
196
  month: int,
188
197
  day: int
189
- ) -> None:
198
+ ) -> list[str]:
190
199
  """
191
200
  Download and decompress e-Callisto FITS files, saving them as `spectre` batch files.
192
201
 
@@ -194,6 +203,7 @@ def download_callisto_data(
194
203
  :param year: Year of the observation.
195
204
  :param month: Month of the observation.
196
205
  :param day: Day of the observation.
206
+ :return: A list of file names of all newly created batch files, relative to `SPECTRE_DATA_DIR_PATH`.
197
207
  """
198
208
  tmp_dir = os.path.join(get_spectre_data_dir_path(), "tmp")
199
209
  # if there are any residual files in the temporary directory, remove them.
@@ -202,5 +212,4 @@ def download_callisto_data(
202
212
  os.makedirs(tmp_dir, exist_ok=True)
203
213
 
204
214
  _wget_callisto_data(instrument_code.value, year, month, day, tmp_dir)
205
- _unzip_to_batches(tmp_dir)
206
- shutil.rmtree(tmp_dir)
215
+ return sorted( _unzip_to_batches(tmp_dir) )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: spectre-core
3
- Version: 0.0.15
3
+ Version: 0.0.17
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