spectre-core 0.0.21__py3-none-any.whl → 0.0.23__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. spectre_core/_file_io/__init__.py +5 -5
  2. spectre_core/_file_io/file_handlers.py +61 -107
  3. spectre_core/batches/__init__.py +21 -4
  4. spectre_core/batches/_base.py +86 -135
  5. spectre_core/batches/_batches.py +56 -100
  6. spectre_core/batches/_factory.py +22 -21
  7. spectre_core/batches/_register.py +9 -9
  8. spectre_core/batches/plugins/_batch_keys.py +8 -7
  9. spectre_core/batches/plugins/_callisto.py +66 -98
  10. spectre_core/batches/plugins/_iq_stream.py +106 -170
  11. spectre_core/capture_configs/__init__.py +47 -18
  12. spectre_core/capture_configs/_capture_config.py +26 -53
  13. spectre_core/capture_configs/_capture_modes.py +9 -7
  14. spectre_core/capture_configs/_capture_templates.py +51 -111
  15. spectre_core/capture_configs/_parameters.py +38 -75
  16. spectre_core/capture_configs/_pconstraints.py +41 -41
  17. spectre_core/capture_configs/_pnames.py +37 -35
  18. spectre_core/capture_configs/_ptemplates.py +261 -348
  19. spectre_core/capture_configs/_pvalidators.py +99 -102
  20. spectre_core/config/__init__.py +14 -9
  21. spectre_core/config/_paths.py +19 -36
  22. spectre_core/config/_time_formats.py +7 -6
  23. spectre_core/exceptions.py +39 -1
  24. spectre_core/jobs/__init__.py +4 -7
  25. spectre_core/jobs/_duration.py +12 -0
  26. spectre_core/jobs/_jobs.py +73 -44
  27. spectre_core/jobs/_workers.py +56 -106
  28. spectre_core/logs/__init__.py +8 -3
  29. spectre_core/logs/_configure.py +14 -18
  30. spectre_core/logs/_decorators.py +7 -5
  31. spectre_core/logs/_logs.py +38 -90
  32. spectre_core/logs/_process_types.py +6 -4
  33. spectre_core/plotting/__init__.py +14 -4
  34. spectre_core/plotting/_base.py +65 -139
  35. spectre_core/plotting/_format.py +11 -9
  36. spectre_core/plotting/_panel_names.py +8 -6
  37. spectre_core/plotting/_panel_stack.py +83 -116
  38. spectre_core/plotting/_panels.py +121 -156
  39. spectre_core/post_processing/__init__.py +7 -4
  40. spectre_core/post_processing/_base.py +69 -69
  41. spectre_core/post_processing/_factory.py +15 -12
  42. spectre_core/post_processing/_post_processor.py +17 -13
  43. spectre_core/post_processing/_register.py +11 -8
  44. spectre_core/post_processing/plugins/_event_handler_keys.py +5 -4
  45. spectre_core/post_processing/plugins/_fixed_center_frequency.py +55 -48
  46. spectre_core/post_processing/plugins/_swept_center_frequency.py +200 -175
  47. spectre_core/receivers/__init__.py +10 -3
  48. spectre_core/receivers/_base.py +83 -149
  49. spectre_core/receivers/_factory.py +21 -31
  50. spectre_core/receivers/_register.py +8 -11
  51. spectre_core/receivers/_spec_names.py +18 -16
  52. spectre_core/receivers/plugins/_b200mini.py +48 -61
  53. spectre_core/receivers/plugins/_receiver_names.py +9 -7
  54. spectre_core/receivers/plugins/_rsp1a.py +45 -41
  55. spectre_core/receivers/plugins/_rspduo.py +60 -45
  56. spectre_core/receivers/plugins/_sdrplay_receiver.py +68 -84
  57. spectre_core/receivers/plugins/_test.py +137 -130
  58. spectre_core/receivers/plugins/_usrp.py +94 -86
  59. spectre_core/receivers/plugins/gr/__init__.py +2 -2
  60. spectre_core/receivers/plugins/gr/_base.py +15 -23
  61. spectre_core/receivers/plugins/gr/_rsp1a.py +53 -60
  62. spectre_core/receivers/plugins/gr/_rspduo.py +78 -90
  63. spectre_core/receivers/plugins/gr/_test.py +50 -58
  64. spectre_core/receivers/plugins/gr/_usrp.py +61 -59
  65. spectre_core/spectrograms/__init__.py +22 -14
  66. spectre_core/spectrograms/_analytical.py +109 -100
  67. spectre_core/spectrograms/_array_operations.py +40 -47
  68. spectre_core/spectrograms/_spectrogram.py +290 -323
  69. spectre_core/spectrograms/_transform.py +107 -74
  70. spectre_core/wgetting/__init__.py +2 -4
  71. spectre_core/wgetting/_callisto.py +88 -94
  72. {spectre_core-0.0.21.dist-info → spectre_core-0.0.23.dist-info}/METADATA +9 -23
  73. spectre_core-0.0.23.dist-info/RECORD +79 -0
  74. {spectre_core-0.0.21.dist-info → spectre_core-0.0.23.dist-info}/WHEEL +1 -1
  75. spectre_core-0.0.21.dist-info/RECORD +0 -78
  76. {spectre_core-0.0.21.dist-info → spectre_core-0.0.23.dist-info}/licenses/LICENSE +0 -0
  77. {spectre_core-0.0.21.dist-info → spectre_core-0.0.23.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
1
+ # SPDX-FileCopyrightText: © 2024-2025 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
2
2
  # This file is part of SPECTRE
3
3
  # SPDX-License-Identifier: GPL-3.0-or-later
4
4
 
@@ -7,38 +7,34 @@ from abc import ABC, abstractmethod
7
7
  from typing import TypeVar, Optional, Any, Generic
8
8
 
9
9
  # value type
10
- VT = TypeVar('VT')
10
+ VT = TypeVar("VT")
11
+
11
12
 
12
13
  class BasePConstraint(ABC, Generic[VT]):
13
14
  """An abstract base class for an arbitary parameter constraint."""
15
+
14
16
  @abstractmethod
15
- def constrain(
16
- self,
17
- value: VT
18
- ) -> None:
17
+ def constrain(self, value: VT) -> None:
19
18
  """Apply a constraint to the input parameter. Implementations must raise a `ValueError` for
20
19
  if the input value fails the constraint.
21
20
 
22
21
  :param value: The value to be constrained.
23
22
  """
24
-
25
-
26
- def __format__(
27
- self,
28
- format_spec: str = ""
29
- ) -> str:
23
+
24
+ def __format__(self, format_spec: str = "") -> str:
30
25
  attrs = ", ".join(f"{key}={value!r}" for key, value in vars(self).items())
31
26
  return f"{self.__class__.__name__}({attrs})"
32
27
 
33
28
 
34
29
  class Bound(BasePConstraint[float | int]):
35
30
  """Bound a numeric parameter value to a some specified interval."""
31
+
36
32
  def __init__(
37
33
  self,
38
34
  lower_bound: Optional[float | int] = None,
39
35
  upper_bound: Optional[float | int] = None,
40
36
  strict_lower: bool = False,
41
- strict_upper: bool = False
37
+ strict_upper: bool = False,
42
38
  ) -> None:
43
39
  """Create an instance of `Bound`.
44
40
 
@@ -52,10 +48,7 @@ class Bound(BasePConstraint[float | int]):
52
48
  self._strict_lower = strict_lower
53
49
  self._strict_upper = strict_upper
54
50
 
55
- def constrain(
56
- self,
57
- value: float | int
58
- ) -> None:
51
+ def constrain(self, value: float | int) -> None:
59
52
  """Bound the parameter value to a specified interval.
60
53
 
61
54
  :param value: The value to be constrained.
@@ -63,28 +56,37 @@ class Bound(BasePConstraint[float | int]):
63
56
  """
64
57
  if self._lower_bound is not None:
65
58
  if self._strict_lower and value <= self._lower_bound:
66
- raise ValueError(f"Value must be strictly greater than {self._lower_bound}. "
67
- f"Got {value}.")
59
+ raise ValueError(
60
+ f"Value must be strictly greater than {self._lower_bound}. "
61
+ f"Got {value}."
62
+ )
68
63
  if not self._strict_lower and value < self._lower_bound:
69
- raise ValueError(f"Value must be greater than or equal to {self._lower_bound}. "
70
- f"Got {value}.")
64
+ raise ValueError(
65
+ f"Value must be greater than or equal to {self._lower_bound}. "
66
+ f"Got {value}."
67
+ )
71
68
 
72
69
  if self._upper_bound is not None:
73
70
  if self._strict_upper and value >= self._upper_bound:
74
- raise ValueError(f"Value must be strictly less than {self._upper_bound}. "
75
- f"Got {value}.")
71
+ raise ValueError(
72
+ f"Value must be strictly less than {self._upper_bound}. "
73
+ f"Got {value}."
74
+ )
76
75
  if not self._strict_upper and value > self._upper_bound:
77
- raise ValueError(f"Value must be less than or equal to {self._upper_bound}. "
78
- f"Got {value}.")
76
+ raise ValueError(
77
+ f"Value must be less than or equal to {self._upper_bound}. "
78
+ f"Got {value}."
79
+ )
80
+
79
81
 
80
82
  # option type
81
- OT = TypeVar('OT')
83
+ OT = TypeVar("OT")
84
+
85
+
82
86
  class OneOf(BasePConstraint[OT]):
83
87
  """Constrain a parameter value to be one of a pre-defined list of options."""
84
- def __init__(
85
- self,
86
- options: Optional[list[OT]] = None
87
- ) -> None:
88
+
89
+ def __init__(self, options: Optional[list[OT]] = None) -> None:
88
90
  """Initialise an instance of `OneOf`.
89
91
 
90
92
  :param options: Input values are required to be one of `options`. If no options are provided,
@@ -92,7 +94,6 @@ class OneOf(BasePConstraint[OT]):
92
94
  """
93
95
  self._options = options or []
94
96
 
95
-
96
97
  def constrain(self, value: OT) -> None:
97
98
  """Constrain the input value to be one of a list of pre-defined options.
98
99
 
@@ -101,14 +102,12 @@ class OneOf(BasePConstraint[OT]):
101
102
  """
102
103
  if value not in self._options:
103
104
  raise ValueError(f"Value must be one of {self._options}. Got {value}.")
104
-
105
+
105
106
 
106
107
  class PowerOfTwo(BasePConstraint[int]):
107
108
  """Constrain a numeric parameter value to be a power of two."""
108
- def constrain(
109
- self,
110
- value: int
111
- ) -> None:
109
+
110
+ def constrain(self, value: int) -> None:
112
111
  """Constrain the input value to be a power of two.
113
112
 
114
113
  :param value: The input value to be constrained.
@@ -121,13 +120,14 @@ class PowerOfTwo(BasePConstraint[int]):
121
120
  @dataclass(frozen=True)
122
121
  class EnforceSign:
123
122
  """Enforce the sign of some value.
124
-
123
+
125
124
  :ivar positive: Enforce the value to be strictly positive.
126
125
  :ivar negative: Enforce the value to be strictly negative.
127
126
  :ivar non_negative: Enforce the value to be zero or positive.
128
127
  :ivar non_positive: Enforce the value to be zero or negative.
129
128
  """
130
- positive = Bound(lower_bound=0, strict_lower=True)
131
- negative = Bound(upper_bound=0, strict_upper=True)
132
- non_negative = Bound(lower_bound=0, strict_lower=False)
133
- non_positive = Bound(upper_bound=0, strict_upper=False)
129
+
130
+ positive = Bound(lower_bound=0, strict_lower=True)
131
+ negative = Bound(upper_bound=0, strict_upper=True)
132
+ non_negative = Bound(lower_bound=0, strict_lower=False)
133
+ non_positive = Bound(upper_bound=0, strict_upper=False)
@@ -1,52 +1,54 @@
1
- # SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
1
+ # SPDX-FileCopyrightText: © 2024-2025 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
2
2
  # This file is part of SPECTRE
3
3
  # SPDX-License-Identifier: GPL-3.0-or-later
4
4
 
5
5
  from enum import Enum
6
6
 
7
+
7
8
  class PName(Enum):
8
9
  """A `spectre` capture config parameter name.
9
-
10
+
10
11
  Each `PName` has an associated base parameter template which can be fetched
11
12
  using:
12
-
13
+
13
14
  `get_base_ptemplate`
14
-
15
+
15
16
  All parameters and parameter templates must take on some name in `PName`.
16
17
  To introduce a new parameter/parameter template, you need to create a new `PName`
17
18
  constant.
18
19
  """
19
- CENTER_FREQUENCY = "center_frequency"
20
- MIN_FREQUENCY = "min_frequency"
21
- MAX_FREQUENCY = "max_frequency"
22
- FREQUENCY_STEP = "frequency_step"
23
- FREQUENCY = "frequency"
24
- BANDWIDTH = "bandwidth"
25
- SAMPLE_RATE = "sample_rate"
26
- IF_GAIN = "if_gain"
27
- RF_GAIN = "rf_gain"
28
- AMPLITUDE = "amplitude"
29
- TIME_RESOLUTION = "time_resolution"
20
+
21
+ CENTER_FREQUENCY = "center_frequency"
22
+ MIN_FREQUENCY = "min_frequency"
23
+ MAX_FREQUENCY = "max_frequency"
24
+ FREQUENCY_STEP = "frequency_step"
25
+ FREQUENCY = "frequency"
26
+ BANDWIDTH = "bandwidth"
27
+ SAMPLE_RATE = "sample_rate"
28
+ IF_GAIN = "if_gain"
29
+ RF_GAIN = "rf_gain"
30
+ AMPLITUDE = "amplitude"
31
+ TIME_RESOLUTION = "time_resolution"
30
32
  FREQUENCY_RESOLUTION = "frequency_resolution"
31
- TIME_RANGE = "time_range"
32
- BATCH_SIZE = "batch_size"
33
- WINDOW_TYPE = "window_type"
34
- WINDOW_HOP = "window_hop"
35
- WINDOW_SIZE = "window_size"
36
- EVENT_HANDLER_KEY = "event_handler_key"
37
- WATCH_EXTENSION = "watch_extension"
38
- BATCH_KEY = "batch_key"
39
- SAMPLES_PER_STEP = "samples_per_step"
33
+ TIME_RANGE = "time_range"
34
+ BATCH_SIZE = "batch_size"
35
+ WINDOW_TYPE = "window_type"
36
+ WINDOW_HOP = "window_hop"
37
+ WINDOW_SIZE = "window_size"
38
+ EVENT_HANDLER_KEY = "event_handler_key"
39
+ WATCH_EXTENSION = "watch_extension"
40
+ BATCH_KEY = "batch_key"
41
+ SAMPLES_PER_STEP = "samples_per_step"
40
42
  MIN_SAMPLES_PER_STEP = "min_samples_per_step"
41
43
  MAX_SAMPLES_PER_STEP = "max_samples_per_step"
42
- STEP_INCREMENT = "step_increment"
43
- ORIGIN = "origin"
44
- TELESCOPE = "telescope"
45
- INSTRUMENT = "instrument"
46
- OBJECT = "object"
47
- OBS_LAT = "obs_lat"
48
- OBS_LON = "obs_lon"
49
- OBS_ALT = "obs_alt"
50
- GAIN = "gain"
51
- MASTER_CLOCK_RATE = "master_clock_rate"
52
- WIRE_FORMAT = "wire_format"
44
+ STEP_INCREMENT = "step_increment"
45
+ ORIGIN = "origin"
46
+ TELESCOPE = "telescope"
47
+ INSTRUMENT = "instrument"
48
+ OBJECT = "object"
49
+ OBS_LAT = "obs_lat"
50
+ OBS_LON = "obs_lon"
51
+ OBS_ALT = "obs_alt"
52
+ GAIN = "gain"
53
+ MASTER_CLOCK_RATE = "master_clock_rate"
54
+ WIRE_FORMAT = "wire_format"