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,13 +1,13 @@
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
  """Basic internal file handling capabilities."""
6
6
 
7
7
  from .file_handlers import (
8
- BaseFileHandler, JsonHandler, TextHandler,
8
+ BaseFileHandler,
9
+ JsonHandler,
10
+ TextHandler,
9
11
  )
10
12
 
11
- __all__ = [
12
- "BaseFileHandler", "JsonHandler", "TextHandler"
13
- ]
13
+ __all__ = ["BaseFileHandler", "JsonHandler", "TextHandler"]
@@ -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,14 +7,15 @@ import json
7
7
  from abc import ABC, abstractmethod
8
8
  from typing import Any, Optional, TypeVar, Generic
9
9
 
10
- T = TypeVar('T')
10
+ T = TypeVar("T")
11
+
11
12
 
12
13
  class BaseFileHandler(ABC, Generic[T]):
13
14
  """
14
15
  Base class for handling file operations.
15
16
 
16
- When subclassing, specify the return type of `_read`
17
- using `Generic[T]`.
17
+ When subclassing, specify the return type of `_read`
18
+ using `Generic[T]`.
18
19
 
19
20
  Example:
20
21
  .. code-block:: python
@@ -26,11 +27,9 @@ class BaseFileHandler(ABC, Generic[T]):
26
27
  # Implementation here
27
28
  ...
28
29
  """
30
+
29
31
  def __init__(
30
- self,
31
- parent_dir_path: str,
32
- base_file_name: str,
33
- extension: Optional[str] = None
32
+ self, parent_dir_path: str, base_file_name: str, extension: Optional[str] = None
34
33
  ) -> None:
35
34
  """Initialise a `BaseFileHandler` instance.
36
35
 
@@ -39,130 +38,101 @@ class BaseFileHandler(ABC, Generic[T]):
39
38
  :param extension: The file extension (without the dot), defaults to None
40
39
  """
41
40
  self._data_cache: Optional[T] = None
42
-
41
+
43
42
  self._parent_dir_path = parent_dir_path
44
- self._base_file_name = base_file_name
45
-
43
+ self._base_file_name = base_file_name
44
+
46
45
  if extension == "":
47
46
  extension = None
48
47
  self._extension = extension
49
48
 
50
-
51
49
  @abstractmethod
52
- def _read(
53
- self
54
- ) -> T:
50
+ def _read(self) -> T:
55
51
  """The grunt work to return the file contents.
56
52
 
57
53
  :return: The file contents.
58
54
  """
59
-
60
-
55
+
61
56
  @property
62
- def parent_dir_path(
63
- self
64
- ) -> str:
57
+ def parent_dir_path(self) -> str:
65
58
  """Return the parent directory path for the file."""
66
59
  return self._parent_dir_path
67
-
68
60
 
69
61
  @property
70
- def base_file_name(
71
- self
72
- ) -> str:
62
+ def base_file_name(self) -> str:
73
63
  """Return the file name, stripped of the file extension."""
74
64
  return self._base_file_name
75
-
76
65
 
77
66
  @property
78
- def extension(
79
- self
80
- ) -> Optional[str]:
67
+ def extension(self) -> Optional[str]:
81
68
  """Return the file path suffix, excluding the dot."""
82
69
  return self._extension
83
-
84
70
 
85
71
  @property
86
- def file_name(
87
- self
88
- ) -> str:
72
+ def file_name(self) -> str:
89
73
  """Generate the file name based on the base name and extension.
90
74
 
91
75
  :return: The file name with the extension (including the dot), or the base name if no extension is set.
92
76
  """
93
- return self._base_file_name if (self._extension is None) else f"{self._base_file_name}.{self._extension}"
94
-
77
+ return (
78
+ self._base_file_name
79
+ if (self._extension is None)
80
+ else f"{self._base_file_name}.{self._extension}"
81
+ )
95
82
 
96
83
  @property
97
- def file_path(
98
- self
99
- ) -> str:
84
+ def file_path(self) -> str:
100
85
  """The absolute or relative file path as defined by the parent directory path,
101
86
  base file name and extension."""
102
87
  return os.path.join(self._parent_dir_path, self.file_name)
103
-
104
-
88
+
105
89
  @property
106
- def exists(
107
- self
108
- ) -> bool:
90
+ def exists(self) -> bool:
109
91
  """Check if the file exists in the filesystem."""
110
- return os.path.exists(self.file_path)
111
-
92
+ return os.path.exists(self.file_path)
112
93
 
113
- def read(
114
- self,
115
- cache: bool = True
116
- ) -> T:
94
+ def read(self, cache: bool = True) -> T:
117
95
  """Read the file contents.
118
-
96
+
119
97
  :param cache: If False, bypasses the cache and reads the file directly on each `read` call, defaults to True
120
98
  :return: The file contents.
121
99
  """
122
100
  # if the user has specified to ignore the cache, simply read the file.
123
101
  if not cache:
124
102
  return self._read()
125
-
103
+
126
104
  # otherwise make use of the cache
127
105
  if self._data_cache is None:
128
106
  self._data_cache = self._read()
129
107
  return self._data_cache
130
-
131
-
132
- def make_parent_dir_path(
133
- self
134
- ) -> None:
135
- """Make the parent directory path of the file. No error is raised if the target
108
+
109
+ def make_parent_dir_path(self) -> None:
110
+ """Make the parent directory path of the file. No error is raised if the target
136
111
  directory already exists.
137
112
  """
138
- os.makedirs(self.parent_dir_path, exist_ok=True)
139
-
113
+ os.makedirs(self.parent_dir_path, exist_ok=True)
140
114
 
141
- def delete(
142
- self,
143
- ignore_if_missing: bool = False
144
- ) -> None:
115
+ def delete(self, ignore_if_missing: bool = False) -> None:
145
116
  """Delete the file from the filesystem.
146
117
 
147
118
  :param ignore_if_missing: If True, skips deletion if the file does not exist, defaults to False
148
119
  :raises FileNotFoundError: If the file is missing and `ignore_if_missing` is False.
149
120
  """
150
121
  if not self.exists and not ignore_if_missing:
151
- raise FileNotFoundError(f"{self.file_name} does not exist, and so cannot be deleted")
122
+ raise FileNotFoundError(
123
+ f"{self.file_name} does not exist, and so cannot be deleted"
124
+ )
152
125
  else:
153
126
  os.remove(self.file_path)
154
-
155
127
 
156
- def cat(
157
- self
158
- ) -> None:
128
+ def cat(self) -> None:
159
129
  """Display the file contents on the standard output."""
160
130
  print(self.read())
161
131
 
162
132
 
163
133
  class JsonHandler(BaseFileHandler[dict[str, Any]]):
164
134
  """File handler for JSON formatted files.
165
-
135
+
166
136
  We assume that the files are of the form
167
137
  {
168
138
  "foo": <JSON compatable structure>
@@ -170,29 +140,17 @@ class JsonHandler(BaseFileHandler[dict[str, Any]]):
170
140
  }
171
141
 
172
142
  """
143
+
173
144
  def __init__(
174
- self,
175
- parent_dir_path: str,
176
- base_file_name: str,
177
- extension: str = "json"
145
+ self, parent_dir_path: str, base_file_name: str, extension: str = "json"
178
146
  ) -> None:
179
- super().__init__(parent_dir_path,
180
- base_file_name,
181
- extension)
182
-
183
-
184
- def _read(
185
- self
186
- ) -> dict[str, Any]:
187
- with open(self.file_path, 'r') as f:
147
+ super().__init__(parent_dir_path, base_file_name, extension)
148
+
149
+ def _read(self) -> dict[str, Any]:
150
+ with open(self.file_path, "r") as f:
188
151
  return json.load(f)
189
-
190
-
191
- def save(
192
- self,
193
- d: dict[str, Any],
194
- force: bool = False
195
- ) -> None:
152
+
153
+ def save(self, d: dict[str, Any], force: bool = False) -> None:
196
154
  """Save the input dictionary to file in the JSON file format.
197
155
 
198
156
  :param d: The dictionary to save.
@@ -205,29 +163,25 @@ class JsonHandler(BaseFileHandler[dict[str, Any]]):
205
163
  if force:
206
164
  pass
207
165
  else:
208
- raise FileExistsError((f"{self.file_name} already exists, write has been abandoned. "
209
- f"You can override this functionality with `force`"))
166
+ raise FileExistsError(
167
+ (
168
+ f"{self.file_name} already exists, write has been abandoned. "
169
+ f"You can override this functionality with `force`"
170
+ )
171
+ )
210
172
 
211
- with open(self.file_path, 'w') as file:
212
- json.dump(d, file, indent=4)
173
+ with open(self.file_path, "w") as file:
174
+ json.dump(d, file, indent=4)
213
175
 
214
-
215
176
 
216
177
  class TextHandler(BaseFileHandler[str]):
217
178
  """File handler for text formatted files."""
179
+
218
180
  def __init__(
219
- self,
220
- parent_dir_path: str,
221
- base_file_name: str,
222
- extension: str = "txt"
181
+ self, parent_dir_path: str, base_file_name: str, extension: str = "txt"
223
182
  ) -> None:
224
- super().__init__(parent_dir_path,
225
- base_file_name,
226
- extension)
227
-
228
-
229
- def _read(
230
- self
231
- ) -> str:
232
- with open(self.file_path, 'r') as f:
233
- return f.read()
183
+ super().__init__(parent_dir_path, base_file_name, extension)
184
+
185
+ def _read(self) -> str:
186
+ with open(self.file_path, "r") as f:
187
+ return f.read()
@@ -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
 
@@ -10,12 +10,29 @@ from .plugins._batch_keys import BatchKey
10
10
  from .plugins._iq_stream import IQStreamBatch, IQMetadata
11
11
  from .plugins._callisto import CallistoBatch
12
12
 
13
- from ._base import BaseBatch, BatchFile, parse_batch_base_file_name
13
+ from ._base import (
14
+ BaseBatch,
15
+ BatchFile,
16
+ parse_batch_file_name,
17
+ parse_batch_base_file_name,
18
+ )
14
19
  from ._batches import Batches
15
20
  from ._factory import get_batch_cls, get_batch_cls_from_tag
16
21
 
17
22
  __all__ = [
18
- "IQStreamBatch", "IQMetadata", "CallistoBatch", "BaseBatch", "BatchFile",
19
- "Batches", "get_batch_cls", "BatchKey", "get_batch_cls_from_tag", "parse_batch_base_file_name"
23
+ "IQStreamBatch",
24
+ "IQMetadata",
25
+ "CallistoBatch",
26
+ "BaseBatch",
27
+ "BatchFile",
28
+ "Batches",
29
+ "get_batch_cls",
30
+ "BatchKey",
31
+ "get_batch_cls_from_tag",
32
+ "parse_batch_file_name",
20
33
  ]
21
34
 
35
+ # To be deprecated.
36
+ __all__ += [
37
+ "parse_batch_base_file_name",
38
+ ]