spectre-core 0.0.22__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.
- spectre_core/_file_io/__init__.py +4 -4
- spectre_core/_file_io/file_handlers.py +60 -106
- spectre_core/batches/__init__.py +20 -3
- spectre_core/batches/_base.py +85 -134
- spectre_core/batches/_batches.py +55 -99
- spectre_core/batches/_factory.py +21 -20
- spectre_core/batches/_register.py +8 -8
- spectre_core/batches/plugins/_batch_keys.py +7 -6
- spectre_core/batches/plugins/_callisto.py +65 -97
- spectre_core/batches/plugins/_iq_stream.py +105 -169
- spectre_core/capture_configs/__init__.py +46 -17
- spectre_core/capture_configs/_capture_config.py +25 -52
- spectre_core/capture_configs/_capture_modes.py +8 -6
- spectre_core/capture_configs/_capture_templates.py +50 -110
- spectre_core/capture_configs/_parameters.py +37 -74
- spectre_core/capture_configs/_pconstraints.py +40 -40
- spectre_core/capture_configs/_pnames.py +36 -34
- spectre_core/capture_configs/_ptemplates.py +260 -347
- spectre_core/capture_configs/_pvalidators.py +99 -102
- spectre_core/config/__init__.py +13 -8
- spectre_core/config/_paths.py +18 -35
- spectre_core/config/_time_formats.py +6 -5
- spectre_core/exceptions.py +38 -0
- spectre_core/jobs/__init__.py +3 -6
- spectre_core/jobs/_duration.py +12 -0
- spectre_core/jobs/_jobs.py +72 -43
- spectre_core/jobs/_workers.py +55 -105
- spectre_core/logs/__init__.py +7 -2
- spectre_core/logs/_configure.py +13 -17
- spectre_core/logs/_decorators.py +6 -4
- spectre_core/logs/_logs.py +37 -89
- spectre_core/logs/_process_types.py +5 -3
- spectre_core/plotting/__init__.py +13 -3
- spectre_core/plotting/_base.py +64 -138
- spectre_core/plotting/_format.py +10 -8
- spectre_core/plotting/_panel_names.py +7 -5
- spectre_core/plotting/_panel_stack.py +82 -115
- spectre_core/plotting/_panels.py +120 -155
- spectre_core/post_processing/__init__.py +6 -3
- spectre_core/post_processing/_base.py +41 -55
- spectre_core/post_processing/_factory.py +14 -11
- spectre_core/post_processing/_post_processor.py +16 -12
- spectre_core/post_processing/_register.py +10 -7
- spectre_core/post_processing/plugins/_event_handler_keys.py +4 -3
- spectre_core/post_processing/plugins/_fixed_center_frequency.py +54 -47
- spectre_core/post_processing/plugins/_swept_center_frequency.py +199 -174
- spectre_core/receivers/__init__.py +9 -2
- spectre_core/receivers/_base.py +82 -148
- spectre_core/receivers/_factory.py +20 -30
- spectre_core/receivers/_register.py +7 -10
- spectre_core/receivers/_spec_names.py +17 -15
- spectre_core/receivers/plugins/_b200mini.py +47 -60
- spectre_core/receivers/plugins/_receiver_names.py +8 -6
- spectre_core/receivers/plugins/_rsp1a.py +44 -40
- spectre_core/receivers/plugins/_rspduo.py +59 -44
- spectre_core/receivers/plugins/_sdrplay_receiver.py +67 -83
- spectre_core/receivers/plugins/_test.py +136 -129
- spectre_core/receivers/plugins/_usrp.py +93 -85
- spectre_core/receivers/plugins/gr/__init__.py +1 -1
- spectre_core/receivers/plugins/gr/_base.py +14 -22
- spectre_core/receivers/plugins/gr/_rsp1a.py +53 -60
- spectre_core/receivers/plugins/gr/_rspduo.py +77 -89
- spectre_core/receivers/plugins/gr/_test.py +49 -57
- spectre_core/receivers/plugins/gr/_usrp.py +61 -59
- spectre_core/spectrograms/__init__.py +21 -13
- spectre_core/spectrograms/_analytical.py +108 -99
- spectre_core/spectrograms/_array_operations.py +39 -46
- spectre_core/spectrograms/_spectrogram.py +289 -322
- spectre_core/spectrograms/_transform.py +106 -73
- spectre_core/wgetting/__init__.py +1 -3
- spectre_core/wgetting/_callisto.py +87 -93
- {spectre_core-0.0.22.dist-info → spectre_core-0.0.23.dist-info}/METADATA +9 -23
- spectre_core-0.0.23.dist-info/RECORD +79 -0
- {spectre_core-0.0.22.dist-info → spectre_core-0.0.23.dist-info}/WHEEL +1 -1
- spectre_core-0.0.22.dist-info/RECORD +0 -78
- {spectre_core-0.0.22.dist-info → spectre_core-0.0.23.dist-info}/licenses/LICENSE +0 -0
- {spectre_core-0.0.22.dist-info → spectre_core-0.0.23.dist-info}/top_level.txt +0 -0
spectre_core/plotting/_panels.py
CHANGED
@@ -15,15 +15,16 @@ from ._base import BaseSpectrumPanel, BaseTimeSeriesPanel
|
|
15
15
|
from ._panel_names import PanelName
|
16
16
|
|
17
17
|
|
18
|
-
T = TypeVar(
|
18
|
+
T = TypeVar("T")
|
19
|
+
|
20
|
+
|
19
21
|
def _bind_to_colors(
|
20
|
-
values: list[T],
|
21
|
-
|
22
|
-
) -> Iterator[Tuple[T, npt.NDArray[np.float32]]]:
|
22
|
+
values: list[T], cmap: str = "winter"
|
23
|
+
) -> Iterator[Tuple[T, npt.NDArray[np.float32]]]:
|
23
24
|
"""
|
24
25
|
Assign RGBA colors to a list of values using a colormap.
|
25
26
|
|
26
|
-
Each value is mapped linearly to a subset of the unit interval and then converted
|
27
|
+
Each value is mapped linearly to a subset of the unit interval and then converted
|
27
28
|
to an RGBA color using the specified colormap.
|
28
29
|
|
29
30
|
:param values: List of values to map to colors.
|
@@ -39,61 +40,57 @@ class FrequencyCutsPanel(BaseSpectrumPanel):
|
|
39
40
|
"""
|
40
41
|
Panel for visualising spectrogram data as frequency cuts.
|
41
42
|
|
42
|
-
This panel plots spectrums corresponding to specific time instances
|
43
|
-
in the spectrogram. Each cut is drawn as a line plot, optionally normalized
|
43
|
+
This panel plots spectrums corresponding to specific time instances
|
44
|
+
in the spectrogram. Each cut is drawn as a line plot, optionally normalized
|
44
45
|
or converted to decibels above the background.
|
45
46
|
"""
|
47
|
+
|
46
48
|
def __init__(
|
47
|
-
self,
|
48
|
-
spectrogram: Spectrogram,
|
49
|
+
self,
|
50
|
+
spectrogram: Spectrogram,
|
49
51
|
*times: float | str,
|
50
52
|
dBb: bool = False,
|
51
|
-
peak_normalise: bool = False
|
53
|
+
peak_normalise: bool = False,
|
52
54
|
) -> None:
|
53
55
|
"""Initialise an instance of `FrequencyCutsPanel`.
|
54
56
|
|
55
57
|
:param spectrogram: The spectrogram to be visualised.
|
56
|
-
:param *times: Times at which to take frequency cuts. Can be floats (relative time) or
|
58
|
+
:param *times: Times at which to take frequency cuts. Can be floats (relative time) or
|
57
59
|
strings (formatted datetimes).
|
58
60
|
:param dBb: If True, plots the spectrums in decibels above the background. Defaults to False.
|
59
|
-
:param peak_normalise: If True, normalizes each spectrum such that its peak value is 1.
|
61
|
+
:param peak_normalise: If True, normalizes each spectrum such that its peak value is 1.
|
60
62
|
Ignored if `dBb` is True. Defaults to False.
|
61
63
|
"""
|
62
|
-
super().__init__(PanelName.FREQUENCY_CUTS,
|
63
|
-
|
64
|
-
|
64
|
+
super().__init__(PanelName.FREQUENCY_CUTS, spectrogram)
|
65
|
+
|
65
66
|
if len(times) == 0:
|
66
|
-
raise ValueError(
|
67
|
+
raise ValueError(
|
68
|
+
f"You must specify the time of at least one cut in `*times`"
|
69
|
+
)
|
67
70
|
self._times = times
|
68
|
-
|
71
|
+
|
69
72
|
self._dBb = dBb
|
70
73
|
self._peak_normalise = peak_normalise
|
71
74
|
self._frequency_cuts: dict[float | datetime, FrequencyCut] = {}
|
72
75
|
|
73
|
-
|
74
|
-
def get_frequency_cuts(
|
75
|
-
self
|
76
|
-
) -> dict[float | datetime, FrequencyCut]:
|
76
|
+
def get_frequency_cuts(self) -> dict[float | datetime, FrequencyCut]:
|
77
77
|
"""
|
78
78
|
Get the frequency cuts for the specified times.
|
79
79
|
|
80
|
-
Computes and caches the spectrum for each requested time. The results are
|
80
|
+
Computes and caches the spectrum for each requested time. The results are
|
81
81
|
stored as a mapping from time to the corresponding `FrequencyCut`.
|
82
82
|
|
83
83
|
:return: A dictionary mapping each time to its corresponding frequency cut.
|
84
84
|
"""
|
85
85
|
if not self._frequency_cuts:
|
86
86
|
for time in self._times:
|
87
|
-
frequency_cut = self._spectrogram.get_frequency_cut(
|
88
|
-
|
89
|
-
|
87
|
+
frequency_cut = self._spectrogram.get_frequency_cut(
|
88
|
+
time, dBb=self._dBb, peak_normalise=self._peak_normalise
|
89
|
+
)
|
90
90
|
self._frequency_cuts[frequency_cut.time] = frequency_cut
|
91
91
|
return self._frequency_cuts
|
92
|
-
|
93
92
|
|
94
|
-
def get_cut_times(
|
95
|
-
self
|
96
|
-
) -> list[float | datetime]:
|
93
|
+
def get_cut_times(self) -> list[float | datetime]:
|
97
94
|
"""
|
98
95
|
Get the exact times of the frequency cuts.
|
99
96
|
|
@@ -103,40 +100,35 @@ class FrequencyCutsPanel(BaseSpectrumPanel):
|
|
103
100
|
"""
|
104
101
|
frequency_cuts = self.get_frequency_cuts()
|
105
102
|
return list(frequency_cuts.keys())
|
106
|
-
|
107
103
|
|
108
|
-
def draw(
|
109
|
-
self
|
110
|
-
) -> None:
|
104
|
+
def draw(self) -> None:
|
111
105
|
"""Draw the frequency cuts onto the panel."""
|
112
106
|
frequency_cuts = self.get_frequency_cuts()
|
113
107
|
for time, color in self.bind_to_colors():
|
114
108
|
frequency_cut = frequency_cuts[time]
|
115
|
-
self.ax.step(
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
) -> None:
|
109
|
+
self.ax.step(
|
110
|
+
self.frequencies, # convert to MHz
|
111
|
+
frequency_cut.cut,
|
112
|
+
where="mid",
|
113
|
+
color=color,
|
114
|
+
)
|
115
|
+
|
116
|
+
def annotate_yaxis(self) -> None:
|
124
117
|
"""Annotate the y-axis of the panel based on the current state.
|
125
118
|
|
126
119
|
The y-axis label reflects whether the data is in decibels above the background (`dBb`),
|
127
120
|
normalized to peak values, or in the original units of the spectrogram.
|
128
121
|
"""
|
129
122
|
if self._dBb:
|
130
|
-
self.ax.set_ylabel(
|
123
|
+
self.ax.set_ylabel("dBb")
|
131
124
|
elif self._peak_normalise:
|
132
125
|
# no y-axis label if we are peak normalising
|
133
|
-
return
|
126
|
+
return
|
134
127
|
else:
|
135
|
-
self.ax.set_ylabel(f
|
128
|
+
self.ax.set_ylabel(f"{self._spectrogram.spectrum_unit.value.capitalize()}")
|
136
129
|
|
137
|
-
|
138
130
|
def bind_to_colors(
|
139
|
-
self
|
131
|
+
self,
|
140
132
|
) -> Iterator[Tuple[float | datetime, npt.NDArray[np.float32]]]:
|
141
133
|
"""
|
142
134
|
Bind each frequency cut time to an RGBA color.
|
@@ -145,73 +137,71 @@ class FrequencyCutsPanel(BaseSpectrumPanel):
|
|
145
137
|
|
146
138
|
:return: An iterator of tuples, each containing a cut time and its corresponding RGBA color.
|
147
139
|
"""
|
148
|
-
return _bind_to_colors(self.get_cut_times(), cmap
|
149
|
-
|
150
|
-
|
140
|
+
return _bind_to_colors(self.get_cut_times(), cmap=self.panel_format.line_cmap)
|
141
|
+
|
142
|
+
|
151
143
|
class TimeCutsPanel(BaseTimeSeriesPanel):
|
152
144
|
"""
|
153
145
|
Panel for visualising spectrogram data as time series of spectral components.
|
154
146
|
|
155
|
-
This panel plots the time evolution of spectral components at specific
|
156
|
-
frequencies in the spectrogram. Each time series is drawn as a line plot,
|
147
|
+
This panel plots the time evolution of spectral components at specific
|
148
|
+
frequencies in the spectrogram. Each time series is drawn as a line plot,
|
157
149
|
optionally normalized, background-subtracted, or converted to decibels above the background.
|
158
150
|
"""
|
151
|
+
|
159
152
|
def __init__(
|
160
|
-
self,
|
161
|
-
spectrogram: Spectrogram,
|
153
|
+
self,
|
154
|
+
spectrogram: Spectrogram,
|
162
155
|
*frequencies: float,
|
163
156
|
dBb: bool = False,
|
164
157
|
peak_normalise: bool = False,
|
165
|
-
background_subtract: bool = False
|
158
|
+
background_subtract: bool = False,
|
166
159
|
) -> None:
|
167
160
|
"""Initialise an instance of `TimeCutsPanel`.
|
168
161
|
|
169
162
|
:param spectrogram: The spectrogram to be visualised.
|
170
163
|
:param *frequencies: Frequencies at which to extract time series.
|
171
164
|
:param dBb: If True, returns the cuts in decibels above the background. Defaults to False.
|
172
|
-
:param peak_normalise: If True, normalizes each time series so its peak value is 1.
|
165
|
+
:param peak_normalise: If True, normalizes each time series so its peak value is 1.
|
173
166
|
Ignored if `dBb` is True. Defaults to False.
|
174
|
-
:param background_subtract: If True, subtracts the background from each time series.
|
167
|
+
:param background_subtract: If True, subtracts the background from each time series.
|
175
168
|
Ignored if `dBb` is True. Defaults to False.
|
176
169
|
"""
|
177
|
-
super().__init__(PanelName.TIME_CUTS,
|
178
|
-
|
179
|
-
|
170
|
+
super().__init__(PanelName.TIME_CUTS, spectrogram)
|
171
|
+
|
180
172
|
if len(frequencies) == 0:
|
181
|
-
raise ValueError(
|
173
|
+
raise ValueError(
|
174
|
+
f"You must specify the frequency of at least one cut in `*frequencies`."
|
175
|
+
)
|
182
176
|
self._frequencies = frequencies
|
183
|
-
|
177
|
+
|
184
178
|
self._dBb = dBb
|
185
179
|
self._peak_normalise = peak_normalise
|
186
180
|
self._background_subtract = background_subtract
|
187
|
-
self._time_cuts: dict[float, TimeCut] = {}
|
188
|
-
|
181
|
+
self._time_cuts: dict[float, TimeCut] = {}
|
189
182
|
|
190
|
-
def get_time_cuts(
|
191
|
-
self
|
192
|
-
) -> dict[float, TimeCut]:
|
183
|
+
def get_time_cuts(self) -> dict[float, TimeCut]:
|
193
184
|
"""
|
194
185
|
Get the time cuts for the specified frequencies.
|
195
186
|
|
196
|
-
Computes and caches the time series for each requested frequency. The results
|
187
|
+
Computes and caches the time series for each requested frequency. The results
|
197
188
|
are stored as a mapping from frequency to `TimeCut`.
|
198
189
|
|
199
190
|
:return: A dictionary mapping each frequency to its corresponding time cut.
|
200
191
|
"""
|
201
192
|
if not self._time_cuts:
|
202
193
|
for frequency in self._frequencies:
|
203
|
-
time_cut =
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
194
|
+
time_cut = self._spectrogram.get_time_cut(
|
195
|
+
frequency,
|
196
|
+
dBb=self._dBb,
|
197
|
+
peak_normalise=self._peak_normalise,
|
198
|
+
correct_background=self._background_subtract,
|
199
|
+
return_time_type=self.time_type,
|
200
|
+
)
|
208
201
|
self._time_cuts[time_cut.frequency] = time_cut
|
209
202
|
return self._time_cuts
|
210
|
-
|
211
203
|
|
212
|
-
def get_frequencies(
|
213
|
-
self
|
214
|
-
) -> list[float]:
|
204
|
+
def get_frequencies(self) -> list[float]:
|
215
205
|
"""
|
216
206
|
Get the exact frequencies for the spectral components being plotted.
|
217
207
|
|
@@ -220,23 +210,14 @@ class TimeCutsPanel(BaseTimeSeriesPanel):
|
|
220
210
|
time_cuts = self.get_time_cuts()
|
221
211
|
return list(time_cuts.keys())
|
222
212
|
|
223
|
-
|
224
|
-
def draw(
|
225
|
-
self
|
226
|
-
) -> None:
|
213
|
+
def draw(self) -> None:
|
227
214
|
"""Draw the time series for each spectral component onto the panel."""
|
228
215
|
time_cuts = self.get_time_cuts()
|
229
216
|
for frequency, color in self.bind_to_colors():
|
230
217
|
time_cut = time_cuts[frequency]
|
231
|
-
self.ax.step(self.times,
|
232
|
-
|
233
|
-
|
234
|
-
color = color)
|
235
|
-
|
236
|
-
|
237
|
-
def annotate_yaxis(
|
238
|
-
self
|
239
|
-
) -> None:
|
218
|
+
self.ax.step(self.times, time_cut.cut, where="mid", color=color)
|
219
|
+
|
220
|
+
def annotate_yaxis(self) -> None:
|
240
221
|
"""
|
241
222
|
Annotate the y-axis of the panel based on the current state.
|
242
223
|
|
@@ -244,16 +225,13 @@ class TimeCutsPanel(BaseTimeSeriesPanel):
|
|
244
225
|
normalized to peak values, or in the original units of the spectrogram.
|
245
226
|
"""
|
246
227
|
if self._dBb:
|
247
|
-
self.ax.set_ylabel(
|
228
|
+
self.ax.set_ylabel("dBb")
|
248
229
|
elif self._peak_normalise:
|
249
|
-
return
|
230
|
+
return # no y-axis label if we are peak normalising.
|
250
231
|
else:
|
251
|
-
self.ax.set_ylabel(f
|
232
|
+
self.ax.set_ylabel(f"{self._spectrogram.spectrum_unit.value.capitalize()}")
|
252
233
|
|
253
|
-
|
254
|
-
def bind_to_colors(
|
255
|
-
self
|
256
|
-
) -> Iterator[Tuple[float, npt.NDArray[np.float32]]]:
|
234
|
+
def bind_to_colors(self) -> Iterator[Tuple[float, npt.NDArray[np.float32]]]:
|
257
235
|
"""
|
258
236
|
Bind each spectral component's frequency to an RGBA color.
|
259
237
|
|
@@ -261,53 +239,56 @@ class TimeCutsPanel(BaseTimeSeriesPanel):
|
|
261
239
|
|
262
240
|
:return: An iterator of tuples, each containing a frequency and its corresponding RGBA color.
|
263
241
|
"""
|
264
|
-
return _bind_to_colors(self.get_frequencies(), cmap
|
265
|
-
|
242
|
+
return _bind_to_colors(self.get_frequencies(), cmap=self.panel_format.line_cmap)
|
243
|
+
|
266
244
|
|
267
245
|
class IntegralOverFrequencyPanel(BaseTimeSeriesPanel):
|
268
246
|
"""Panel for visualising the spectrogram integrated over frequency.
|
269
247
|
|
270
|
-
This panel plots the spectrogram numerically integrated over frequency as a time
|
271
|
-
series. The result can be normalized to its peak value or adjusted by subtracting
|
248
|
+
This panel plots the spectrogram numerically integrated over frequency as a time
|
249
|
+
series. The result can be normalized to its peak value or adjusted by subtracting
|
272
250
|
the background.
|
273
251
|
"""
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
252
|
+
|
253
|
+
def __init__(
|
254
|
+
self,
|
255
|
+
spectrogram: Spectrogram,
|
256
|
+
peak_normalise: bool = False,
|
257
|
+
background_subtract: bool = False,
|
258
|
+
):
|
278
259
|
"""Initialise an instance of `IntegralOverFrequencyPanel`.
|
279
|
-
|
260
|
+
|
280
261
|
:param spectrogram: The spectrogram to be visualised.
|
281
262
|
:param peak_normalise: If True, normalizes the integral so its peak value is 1. Defaults to False.
|
282
263
|
:param background_subtract: If True, subtracts the background after computing the integral. Defaults to False.
|
283
264
|
"""
|
284
|
-
super().__init__(PanelName.INTEGRAL_OVER_FREQUENCY,
|
285
|
-
spectrogram)
|
265
|
+
super().__init__(PanelName.INTEGRAL_OVER_FREQUENCY, spectrogram)
|
286
266
|
self._peak_normalise = peak_normalise
|
287
267
|
self._background_subtract = background_subtract
|
288
268
|
|
289
|
-
|
290
269
|
def draw(self):
|
291
270
|
"""Integrate the spectrogram over frequency and plot the result."""
|
292
|
-
I = self._spectrogram.integrate_over_frequency(
|
293
|
-
|
294
|
-
|
295
|
-
|
271
|
+
I = self._spectrogram.integrate_over_frequency(
|
272
|
+
correct_background=self._background_subtract,
|
273
|
+
peak_normalise=self._peak_normalise,
|
274
|
+
)
|
275
|
+
self.ax.step(self.times, I, where="mid", color=self.panel_format.line_color)
|
296
276
|
|
297
277
|
def annotate_yaxis(self):
|
298
278
|
"""This panel does not annotate the y-axis."""
|
299
|
-
|
300
|
-
|
279
|
+
|
280
|
+
|
301
281
|
class SpectrogramPanel(BaseTimeSeriesPanel):
|
302
282
|
"""
|
303
283
|
Panel for visualising the full spectrogram.
|
304
284
|
|
305
|
-
This panel plots the spectrogram as a colormap, with optional log normalization or
|
285
|
+
This panel plots the spectrogram as a colormap, with optional log normalization or
|
306
286
|
in units of decibels above the background.
|
307
287
|
"""
|
288
|
+
|
308
289
|
def __init__(
|
309
|
-
self,
|
310
|
-
spectrogram: Spectrogram,
|
290
|
+
self,
|
291
|
+
spectrogram: Spectrogram,
|
311
292
|
log_norm: bool = False,
|
312
293
|
dBb: bool = False,
|
313
294
|
vmin: Optional[float] = None,
|
@@ -321,25 +302,23 @@ class SpectrogramPanel(BaseTimeSeriesPanel):
|
|
321
302
|
:param vmin: Minimum value for the colormap. Only applies if `dBb` is True. Defaults to None.
|
322
303
|
:param vmax: Maximum value for the colormap. Only applies if `dBb` is True. Defaults to None.
|
323
304
|
"""
|
324
|
-
super().__init__(PanelName.SPECTROGRAM,
|
325
|
-
spectrogram)
|
305
|
+
super().__init__(PanelName.SPECTROGRAM, spectrogram)
|
326
306
|
self._log_norm = log_norm
|
327
307
|
self._dBb = dBb
|
328
308
|
self._vmin = vmin
|
329
309
|
self._vmax = vmax
|
330
310
|
|
331
|
-
|
332
311
|
def _draw_dBb(self) -> None:
|
333
312
|
"""Plot the spectrogram in decibels above the background (dBb).
|
334
313
|
|
335
|
-
This method handles plotting the spectrogram with dBb scaling, applying
|
314
|
+
This method handles plotting the spectrogram with dBb scaling, applying
|
336
315
|
colormap bounds (`vmin` and `vmax`) and adding a colorbar to the panel.
|
337
316
|
"""
|
338
317
|
dynamic_spectra = self._spectrogram.compute_dynamic_spectra_dBb()
|
339
|
-
|
318
|
+
|
340
319
|
# use defaults if neither vmin or vmax is specified
|
341
320
|
vmin = self._vmin or -1
|
342
|
-
vmax = self._vmax or
|
321
|
+
vmax = self._vmax or 2
|
343
322
|
|
344
323
|
# Plot the spectrogram
|
345
324
|
pcm = self.ax.pcolormesh(
|
@@ -356,19 +335,19 @@ class SpectrogramPanel(BaseTimeSeriesPanel):
|
|
356
335
|
cbar = self.fig.colorbar(pcm, ax=self.ax, ticks=cbar_ticks)
|
357
336
|
cbar.set_label("dBb")
|
358
337
|
|
359
|
-
|
360
338
|
def _draw_normal(self) -> None:
|
361
339
|
"""Plot the spectrogram with optional logarithmic normalization.
|
362
340
|
|
363
|
-
This method handles plotting the spectrogram without dBb scaling, using
|
341
|
+
This method handles plotting the spectrogram without dBb scaling, using
|
364
342
|
linear or log normalization based on the `log_norm` attribute.
|
365
343
|
"""
|
366
344
|
dynamic_spectra = self._spectrogram.dynamic_spectra
|
367
|
-
|
368
345
|
|
369
346
|
if self._log_norm:
|
370
|
-
norm = LogNorm(
|
371
|
-
|
347
|
+
norm = LogNorm(
|
348
|
+
vmin=np.nanmin(dynamic_spectra[dynamic_spectra > 0]),
|
349
|
+
vmax=np.nanmax(dynamic_spectra),
|
350
|
+
)
|
372
351
|
else:
|
373
352
|
norm = None
|
374
353
|
|
@@ -381,7 +360,6 @@ class SpectrogramPanel(BaseTimeSeriesPanel):
|
|
381
360
|
norm=norm,
|
382
361
|
)
|
383
362
|
|
384
|
-
|
385
363
|
def draw(self) -> None:
|
386
364
|
"""Draw the spectrogram onto the panel."""
|
387
365
|
if self._dBb:
|
@@ -389,46 +367,33 @@ class SpectrogramPanel(BaseTimeSeriesPanel):
|
|
389
367
|
else:
|
390
368
|
self._draw_normal()
|
391
369
|
|
392
|
-
|
393
|
-
def annotate_yaxis(
|
394
|
-
self
|
395
|
-
) -> None:
|
370
|
+
def annotate_yaxis(self) -> None:
|
396
371
|
"""Annotate the yaxis, assuming units of Hz."""
|
397
|
-
self.ax.set_ylabel(
|
372
|
+
self.ax.set_ylabel("Frequency [Hz]")
|
398
373
|
return
|
399
|
-
|
400
|
-
|
401
|
-
def overlay_time_cuts(
|
402
|
-
self,
|
403
|
-
cuts_panel: TimeCutsPanel
|
404
|
-
) -> None:
|
374
|
+
|
375
|
+
def overlay_time_cuts(self, cuts_panel: TimeCutsPanel) -> None:
|
405
376
|
"""
|
406
377
|
Overlay horizontal lines on the spectrogram to indicate time cuts.
|
407
378
|
|
408
|
-
The lines correspond to the frequencies of the cuts on a `TimeCutsPanel`.
|
379
|
+
The lines correspond to the frequencies of the cuts on a `TimeCutsPanel`.
|
409
380
|
Colors are matched to the lines on the `TimeCutsPanel`.
|
410
381
|
|
411
382
|
:param cuts_panel: The `TimeCutsPanel` containing the cut frequencies to overlay.
|
412
383
|
"""
|
413
384
|
for frequency, color in cuts_panel.bind_to_colors():
|
414
|
-
self.ax.axhline(
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
def overlay_frequency_cuts(
|
420
|
-
self,
|
421
|
-
cuts_panel: FrequencyCutsPanel
|
422
|
-
) -> None:
|
385
|
+
self.ax.axhline(
|
386
|
+
frequency, color=color, linewidth=self.panel_format.line_width
|
387
|
+
)
|
388
|
+
|
389
|
+
def overlay_frequency_cuts(self, cuts_panel: FrequencyCutsPanel) -> None:
|
423
390
|
"""
|
424
391
|
Overlay vertical lines on the spectrogram to indicate frequency cuts.
|
425
392
|
|
426
|
-
The lines correspond to the times of the cuts on a `FrequencyCutsPanel`.
|
393
|
+
The lines correspond to the times of the cuts on a `FrequencyCutsPanel`.
|
427
394
|
Colors are matched to the lines on the `FrequencyCutsPanel`.
|
428
395
|
|
429
396
|
:param cuts_panel: The `FrequencyCutsPanel` containing the cut times to overlay.
|
430
397
|
"""
|
431
398
|
for time, color in cuts_panel.bind_to_colors():
|
432
|
-
self.ax.axvline(time,
|
433
|
-
color = color,
|
434
|
-
linewidth=self.panel_format.line_width)
|
399
|
+
self.ax.axvline(time, color=color, linewidth=self.panel_format.line_width)
|
@@ -11,6 +11,9 @@ from ._factory import get_event_handler, get_event_handler_cls_from_tag
|
|
11
11
|
from ._post_processor import start_post_processor
|
12
12
|
|
13
13
|
__all__ = [
|
14
|
-
"FixedEventHandler",
|
15
|
-
"
|
16
|
-
|
14
|
+
"FixedEventHandler",
|
15
|
+
"SweptEventHandler",
|
16
|
+
"start_post_processor",
|
17
|
+
"get_event_handler",
|
18
|
+
"get_event_handler_cls_from_tag",
|
19
|
+
]
|