Compare commits
2 Commits
5d909c4a22
...
cfa1da9f4d
| Author | SHA1 | Date | |
|---|---|---|---|
| cfa1da9f4d | |||
| 0e3e022084 |
2186
poetry.lock
generated
2186
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
"""
|
"""
|
||||||
The annotations package contains tools and utilities for creating, managing, and processing annotations.
|
The annotations package contains tools and utilities for creating, managing, and processing annotations.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,10 @@ def _estimate_spectral_bounds(signal_segment: np.ndarray, sample_rate: float) ->
|
||||||
else:
|
else:
|
||||||
runs = _find_ranges(sig_indices, max_gap=max(1, spectral_smooth_bins // 2))
|
runs = _find_ranges(sig_indices, max_gap=max(1, spectral_smooth_bins // 2))
|
||||||
peak_idx = int(np.argmax(smoothed_fft))
|
peak_idx = int(np.argmax(smoothed_fft))
|
||||||
lo_idx, hi_idx = min(runs, key=lambda run: 0 if run[0] <= peak_idx <= run[1] else min(abs(run[0] - peak_idx), abs(run[1] - peak_idx)))
|
lo_idx, hi_idx = min(
|
||||||
|
runs,
|
||||||
|
key=lambda run: 0 if run[0] <= peak_idx <= run[1] else min(abs(run[0] - peak_idx), abs(run[1] - peak_idx)),
|
||||||
|
)
|
||||||
|
|
||||||
# Prevent extremely narrow tone boxes from collapsing to just a few bins.
|
# Prevent extremely narrow tone boxes from collapsing to just a few bins.
|
||||||
min_total_bw_hz = 20_000.0
|
min_total_bw_hz = 20_000.0
|
||||||
|
|
|
||||||
|
|
@ -956,8 +956,10 @@ def get_result_sizes( # noqa: C901 # TODO: Simplify function
|
||||||
# Check that each class that will be augmented does not already suffice target_size
|
# Check that each class that will be augmented does not already suffice target_size
|
||||||
for cls_name, target_size_value in zip(classes_to_augment, target_size):
|
for cls_name, target_size_value in zip(classes_to_augment, target_size):
|
||||||
if class_sizes[cls_name] >= target_size_value:
|
if class_sizes[cls_name] >= target_size_value:
|
||||||
raise ValueError(f"""target_size of {target_size_value} is already sufficed for current size of
|
raise ValueError(
|
||||||
{class_sizes[cls_name]} for class: {cls_name}""")
|
f"""target_size of {target_size_value} is already sufficed for current size of
|
||||||
|
{class_sizes[cls_name]} for class: {cls_name}"""
|
||||||
|
)
|
||||||
|
|
||||||
for index, class_name in enumerate(classes_to_augment):
|
for index, class_name in enumerate(classes_to_augment):
|
||||||
result_sizes[class_name] = target_size[index]
|
result_sizes[class_name] = target_size[index]
|
||||||
|
|
|
||||||
|
|
@ -136,9 +136,9 @@ def from_npy(file: os.PathLike | str, legacy: bool = False) -> Recording:
|
||||||
annotations = []
|
annotations = []
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
# File was pickled with utils.data.Annotation — remap to ria_toolkit_oss
|
# File was pickled with utils.data.Annotation — remap to ria_toolkit_oss
|
||||||
import pickle
|
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
|
|
||||||
import ria_toolkit_oss.datatypes.annotation as _ann_mod
|
import ria_toolkit_oss.datatypes.annotation as _ann_mod
|
||||||
|
|
||||||
utils_shim = types.ModuleType("utils")
|
utils_shim = types.ModuleType("utils")
|
||||||
|
|
|
||||||
|
|
@ -474,8 +474,10 @@ class Blade(SDR):
|
||||||
|
|
||||||
if gain_mode == "relative":
|
if gain_mode == "relative":
|
||||||
if gain > 0:
|
if gain > 0:
|
||||||
raise SDRParameterError("When gain_mode = 'relative', gain must be < 0. This sets \
|
raise SDRParameterError(
|
||||||
the gain relative to the maximum possible gain.")
|
"When gain_mode = 'relative', gain must be < 0. This sets \
|
||||||
|
the gain relative to the maximum possible gain."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
abs_gain = rx_gain_max + gain
|
abs_gain = rx_gain_max + gain
|
||||||
else:
|
else:
|
||||||
|
|
@ -548,8 +550,10 @@ class Blade(SDR):
|
||||||
|
|
||||||
if gain_mode == "relative":
|
if gain_mode == "relative":
|
||||||
if gain > 0:
|
if gain > 0:
|
||||||
raise SDRParameterError("When gain_mode = 'relative', gain must be < 0. This sets\
|
raise SDRParameterError(
|
||||||
the gain relative to the maximum possible gain.")
|
"When gain_mode = 'relative', gain must be < 0. This sets\
|
||||||
|
the gain relative to the maximum possible gain."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
abs_gain = tx_gain_max + gain
|
abs_gain = tx_gain_max + gain
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -172,8 +172,10 @@ class HackRF(SDR):
|
||||||
tx_gain_max = 47
|
tx_gain_max = 47
|
||||||
if gain_mode == "relative":
|
if gain_mode == "relative":
|
||||||
if gain > 0:
|
if gain > 0:
|
||||||
raise SDRParameterError("When gain_mode = 'relative', gain must be < 0. This \
|
raise SDRParameterError(
|
||||||
sets the gain relative to the maximum possible gain.")
|
"When gain_mode = 'relative', gain must be < 0. This \
|
||||||
|
sets the gain relative to the maximum possible gain."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
abs_gain = tx_gain_max + gain
|
abs_gain = tx_gain_max + gain
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -274,16 +274,20 @@ class Pluto(SDR):
|
||||||
data = [self._convert_tx_samples(samples), self._convert_tx_samples(samples)]
|
data = [self._convert_tx_samples(samples), self._convert_tx_samples(samples)]
|
||||||
else:
|
else:
|
||||||
if len(recording) > 2:
|
if len(recording) > 2:
|
||||||
warnings.warn("More recordings were provided than channels in the Pluto. \
|
warnings.warn(
|
||||||
Only the first two recordings will be used")
|
"More recordings were provided than channels in the Pluto. \
|
||||||
|
Only the first two recordings will be used"
|
||||||
|
)
|
||||||
sample0 = self._convert_tx_samples(recording.data[0])
|
sample0 = self._convert_tx_samples(recording.data[0])
|
||||||
sample1 = self._convert_tx_samples(recording.data[1])
|
sample1 = self._convert_tx_samples(recording.data[1])
|
||||||
data = [sample0, sample1]
|
data = [sample0, sample1]
|
||||||
|
|
||||||
elif isinstance(recording, list):
|
elif isinstance(recording, list):
|
||||||
if len(recording) > 2:
|
if len(recording) > 2:
|
||||||
warnings.warn("More recordings were provided than channels in the Pluto. \
|
warnings.warn(
|
||||||
Only the first two recordings will be used")
|
"More recordings were provided than channels in the Pluto. \
|
||||||
|
Only the first two recordings will be used"
|
||||||
|
)
|
||||||
|
|
||||||
if isinstance(recording[0], np.ndarray):
|
if isinstance(recording[0], np.ndarray):
|
||||||
data = [self._convert_tx_samples(recording[0]), self._convert_tx_samples(recording[1])]
|
data = [self._convert_tx_samples(recording[0]), self._convert_tx_samples(recording[1])]
|
||||||
|
|
@ -423,8 +427,10 @@ class Pluto(SDR):
|
||||||
|
|
||||||
if gain_mode == "relative":
|
if gain_mode == "relative":
|
||||||
if gain > 0:
|
if gain > 0:
|
||||||
raise SDRParameterError("When gain_mode = 'relative', gain must be < 0. This sets \
|
raise SDRParameterError(
|
||||||
the gain relative to the maximum possible gain.")
|
"When gain_mode = 'relative', gain must be < 0. This sets \
|
||||||
|
the gain relative to the maximum possible gain."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
abs_gain = rx_gain_max + gain
|
abs_gain = rx_gain_max + gain
|
||||||
else:
|
else:
|
||||||
|
|
@ -534,8 +540,10 @@ class Pluto(SDR):
|
||||||
|
|
||||||
if gain_mode == "relative":
|
if gain_mode == "relative":
|
||||||
if gain > 0:
|
if gain > 0:
|
||||||
raise SDRParameterError("When gain_mode = 'relative', gain must be < 0. This sets\
|
raise SDRParameterError(
|
||||||
the gain relative to the maximum possible gain.")
|
"When gain_mode = 'relative', gain must be < 0. This sets\
|
||||||
|
the gain relative to the maximum possible gain."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
abs_gain = tx_gain_max + gain
|
abs_gain = tx_gain_max + gain
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -131,15 +131,19 @@ class RTLSDR(SDR):
|
||||||
|
|
||||||
if gain_mode == "relative":
|
if gain_mode == "relative":
|
||||||
if gain > 0:
|
if gain > 0:
|
||||||
raise SDRParameterError("When gain_mode = 'relative', gain must be < 0. This sets\
|
raise SDRParameterError(
|
||||||
the gain relative to the maximum possible gain.")
|
"When gain_mode = 'relative', gain must be < 0. This sets\
|
||||||
|
the gain relative to the maximum possible gain."
|
||||||
|
)
|
||||||
target_gain = max_gain + gain
|
target_gain = max_gain + gain
|
||||||
else:
|
else:
|
||||||
target_gain = gain
|
target_gain = gain
|
||||||
|
|
||||||
if target_gain < min_gain or target_gain > max_gain:
|
if target_gain < min_gain or target_gain > max_gain:
|
||||||
print(f"Requested gain {target_gain} dB out of range;\
|
print(
|
||||||
clamping to valid span {min_gain}-{max_gain} dB.")
|
f"Requested gain {target_gain} dB out of range;\
|
||||||
|
clamping to valid span {min_gain}-{max_gain} dB."
|
||||||
|
)
|
||||||
target_gain = min(max(target_gain, min_gain), max_gain)
|
target_gain = min(max(target_gain, min_gain), max_gain)
|
||||||
|
|
||||||
target_gain = min(available_gains, key=lambda g: abs(g - target_gain))
|
target_gain = min(available_gains, key=lambda g: abs(g - target_gain))
|
||||||
|
|
|
||||||
|
|
@ -392,8 +392,10 @@ class ThinkRF(SDR):
|
||||||
actual_sample_rate = self.BASE_SAMPLE_RATE / decimation
|
actual_sample_rate = self.BASE_SAMPLE_RATE / decimation
|
||||||
|
|
||||||
if abs(actual_sample_rate - requested_sample_rate) > 1e3: # More than 1 kHz difference
|
if abs(actual_sample_rate - requested_sample_rate) > 1e3: # More than 1 kHz difference
|
||||||
print(f"ThinkRF: Requested {requested_sample_rate/1e6:.2f} MS/s → \
|
print(
|
||||||
Using decimation={decimation} ({actual_sample_rate/1e6:.2f} MS/s)")
|
f"ThinkRF: Requested {requested_sample_rate/1e6:.2f} MS/s → \
|
||||||
|
Using decimation={decimation} ({actual_sample_rate/1e6:.2f} MS/s)"
|
||||||
|
)
|
||||||
|
|
||||||
return decimation, actual_sample_rate
|
return decimation, actual_sample_rate
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,8 +148,10 @@ class USRP(SDR):
|
||||||
gain_range = self.usrp.get_rx_gain_range()
|
gain_range = self.usrp.get_rx_gain_range()
|
||||||
if gain_mode == "relative":
|
if gain_mode == "relative":
|
||||||
if gain > 0:
|
if gain > 0:
|
||||||
raise SDRParameterError("When gain_mode = 'relative', gain must be < 0. This sets\
|
raise SDRParameterError(
|
||||||
the gain relative to the maximum possible gain.")
|
"When gain_mode = 'relative', gain must be < 0. This sets\
|
||||||
|
the gain relative to the maximum possible gain."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# set gain relative to max
|
# set gain relative to max
|
||||||
abs_gain = gain_range.stop() + gain
|
abs_gain = gain_range.stop() + gain
|
||||||
|
|
@ -354,8 +356,10 @@ class USRP(SDR):
|
||||||
gain_range = self.usrp.get_tx_gain_range()
|
gain_range = self.usrp.get_tx_gain_range()
|
||||||
if gain_mode == "relative":
|
if gain_mode == "relative":
|
||||||
if gain > 0:
|
if gain > 0:
|
||||||
raise SDRParameterError("When gain_mode = 'relative', gain must be < 0. This sets\
|
raise SDRParameterError(
|
||||||
the gain relative to the maximum possible gain.")
|
"When gain_mode = 'relative', gain must be < 0. This sets\
|
||||||
|
the gain relative to the maximum possible gain."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# set gain relative to max
|
# set gain relative to max
|
||||||
abs_gain = gain_range.stop() + gain
|
abs_gain = gain_range.stop() + gain
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,10 @@ class Add(RecordableBlock, ProcessBlock):
|
||||||
|
|
||||||
samples = block.get_samples(num_samples)
|
samples = block.get_samples(num_samples)
|
||||||
if len(samples) != num_samples:
|
if len(samples) != num_samples:
|
||||||
raise ValueError(f"Block {self.__class__.__name__} requested {num_samples} \
|
raise ValueError(
|
||||||
from block {block.__class__.__name__} but got {len(samples)}.")
|
f"Block {self.__class__.__name__} requested {num_samples} \
|
||||||
|
from block {block.__class__.__name__} but got {len(samples)}."
|
||||||
|
)
|
||||||
|
|
||||||
return samples
|
return samples
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from ria_toolkit_oss.signal.block_generator.block import Block
|
from ria_toolkit_oss.signal.block_generator.block import Block
|
||||||
from ria_toolkit_oss.signal.block_generator.data_types import DataType
|
from ria_toolkit_oss.signal.block_generator.data_types import DataType
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,11 @@ class ProcessBlock(Block, ABC):
|
||||||
)
|
)
|
||||||
|
|
||||||
elif not all(isinstance(item, Block) for item in input):
|
elif not all(isinstance(item, Block) for item in input):
|
||||||
raise ValueError(f"Invalid input to block '{self.__class__.__name__}'. \
|
raise ValueError(
|
||||||
|
f"Invalid input to block '{self.__class__.__name__}'. \
|
||||||
Expected a list of Block objects but got \
|
Expected a list of Block objects but got \
|
||||||
{'[' + ',' .join(f'{item.__class__.__name__}({repr(item)})' for item in input) + ']'}")
|
{'[' + ',' .join(f'{item.__class__.__name__}({repr(item)})' for item in input) + ']'}"
|
||||||
|
)
|
||||||
|
|
||||||
elif len(input) != len(self.input_type):
|
elif len(input) != len(self.input_type):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,10 @@ class RecordableBlock(Block, Recordable):
|
||||||
:raises ValueError: If the number of samples is incorrect."""
|
:raises ValueError: If the number of samples is incorrect."""
|
||||||
samples = self.get_samples(num_samples)
|
samples = self.get_samples(num_samples)
|
||||||
if len(samples) != num_samples:
|
if len(samples) != num_samples:
|
||||||
raise ValueError(f"Error in block {self.__class__.__name__} record(). \
|
raise ValueError(
|
||||||
Requested {num_samples} samples but got {len(samples)}")
|
f"Error in block {self.__class__.__name__} record(). \
|
||||||
|
Requested {num_samples} samples but got {len(samples)}"
|
||||||
|
)
|
||||||
metadata = self._get_metadata()
|
metadata = self._get_metadata()
|
||||||
return Recording(data=samples, metadata=metadata)
|
return Recording(data=samples, metadata=metadata)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,9 @@ class RecordingSource(SourceBlock, RecordableBlock):
|
||||||
:raises ValueError: If num_samples is greater than the recording length.
|
:raises ValueError: If num_samples is greater than the recording length.
|
||||||
"""
|
"""
|
||||||
if num_samples - 1 >= self.recording.data.shape[1]:
|
if num_samples - 1 >= self.recording.data.shape[1]:
|
||||||
raise ValueError(f"{num_samples} samples requested from recording source with \
|
raise ValueError(
|
||||||
{self.recording.data.shape[1]} samples available.")
|
f"{num_samples} samples requested from recording source with \
|
||||||
|
{self.recording.data.shape[1]} samples available."
|
||||||
|
)
|
||||||
|
|
||||||
return self.recording.data[0, 0:num_samples]
|
return self.recording.data[0, 0:num_samples]
|
||||||
|
|
|
||||||
|
|
@ -610,8 +610,10 @@ def cut_out( # noqa: C901 # TODO: Simplify function
|
||||||
raise ValueError("signal must be CxN complex.")
|
raise ValueError("signal must be CxN complex.")
|
||||||
|
|
||||||
if fill_type not in {"zeros", "ones", "low-snr", "avg-snr", "high-snr"}:
|
if fill_type not in {"zeros", "ones", "low-snr", "avg-snr", "high-snr"}:
|
||||||
raise UserWarning("""fill_type must be "zeros", "ones", "low-snr", "avg-snr", or "high-snr",
|
raise UserWarning(
|
||||||
"ones" has been selected by default""")
|
"""fill_type must be "zeros", "ones", "low-snr", "avg-snr", or "high-snr",
|
||||||
|
"ones" has been selected by default"""
|
||||||
|
)
|
||||||
|
|
||||||
if max_section_size < 1 or max_section_size >= n:
|
if max_section_size < 1 or max_section_size >= n:
|
||||||
raise ValueError("max_section_size must be at least 1 and must be less than the length of signal.")
|
raise ValueError("max_section_size must be at least 1 and must be less than the length of signal.")
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import textwrap
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from matplotlib.patches import Patch
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from matplotlib import gridspec
|
from matplotlib import gridspec
|
||||||
from matplotlib.patches import Patch
|
from matplotlib.patches import Patch
|
||||||
|
|
@ -14,7 +13,12 @@ from scipy.signal import spectrogram
|
||||||
from scipy.signal.windows import hann
|
from scipy.signal.windows import hann
|
||||||
|
|
||||||
from ria_toolkit_oss.datatypes.recording import Recording
|
from ria_toolkit_oss.datatypes.recording import Recording
|
||||||
from ria_toolkit_oss.view.tools import COLORS, decimate, extract_metadata_fields, set_path
|
from ria_toolkit_oss.view.tools import (
|
||||||
|
COLORS,
|
||||||
|
decimate,
|
||||||
|
extract_metadata_fields,
|
||||||
|
set_path,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_fft_size(plot_length):
|
def get_fft_size(plot_length):
|
||||||
|
|
@ -59,13 +63,6 @@ def view_annotations(
|
||||||
annotations = recording.annotations
|
annotations = recording.annotations
|
||||||
|
|
||||||
# 2. Setup Color Mapping
|
# 2. Setup Color Mapping
|
||||||
available_colors = [
|
|
||||||
COLORS.get("magenta", "magenta"),
|
|
||||||
COLORS.get("accent", "cyan"),
|
|
||||||
COLORS.get("light", "white"),
|
|
||||||
"lime",
|
|
||||||
]
|
|
||||||
|
|
||||||
palette = ["#2196F3", "#9C27B0", "#64B5F6", "#7B1FA2", "#5C6BC0", "#CE93D8", "#1565C0", "#7C4DFF"]
|
palette = ["#2196F3", "#9C27B0", "#64B5F6", "#7B1FA2", "#5C6BC0", "#CE93D8", "#1565C0", "#7C4DFF"]
|
||||||
unique_labels = sorted(list(set(ann.label for ann in annotations if ann.label)))
|
unique_labels = sorted(list(set(ann.label for ann in annotations if ann.label)))
|
||||||
label_to_color = {label: palette[i % len(palette)] for i, label in enumerate(unique_labels)}
|
label_to_color = {label: palette[i % len(palette)] for i, label in enumerate(unique_labels)}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,12 @@ from scipy.fft import fft, fftshift
|
||||||
from scipy.signal.windows import hann
|
from scipy.signal.windows import hann
|
||||||
|
|
||||||
from ria_toolkit_oss.datatypes.recording import Recording
|
from ria_toolkit_oss.datatypes.recording import Recording
|
||||||
from ria_toolkit_oss.view.tools import COLORS, decimate, extract_metadata_fields, set_path
|
from ria_toolkit_oss.view.tools import (
|
||||||
|
COLORS,
|
||||||
|
decimate,
|
||||||
|
extract_metadata_fields,
|
||||||
|
set_path,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _add_annotations(annotations, compact_mode, show_labels, sample_rate_hz, center_freq_hz, ax2):
|
def _add_annotations(annotations, compact_mode, show_labels, sample_rate_hz, center_freq_hz, ax2):
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,10 @@ from ria_toolkit_oss.annotations import (
|
||||||
from ria_toolkit_oss.datatypes import Annotation
|
from ria_toolkit_oss.datatypes import Annotation
|
||||||
from ria_toolkit_oss.datatypes.recording import Recording
|
from ria_toolkit_oss.datatypes.recording import Recording
|
||||||
from ria_toolkit_oss.io import load_recording, to_blue, to_npy, to_sigmf, to_wav
|
from ria_toolkit_oss.io import load_recording, to_blue, to_npy, to_sigmf, to_wav
|
||||||
from ria_toolkit_oss_cli.ria_toolkit_oss.common import format_frequency, format_sample_count
|
from ria_toolkit_oss_cli.ria_toolkit_oss.common import (
|
||||||
|
format_frequency,
|
||||||
|
format_sample_count,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def normalize_sigmf_path(filepath):
|
def normalize_sigmf_path(filepath):
|
||||||
|
|
@ -658,7 +661,12 @@ def cusum(input, label, min_duration, window_size, tolerance, annotation_type, o
|
||||||
@click.argument("input", type=click.Path(exists=True))
|
@click.argument("input", type=click.Path(exists=True))
|
||||||
@click.option("--threshold", type=float, required=True, help="Threshold (0.0-1.0, fraction of max magnitude)")
|
@click.option("--threshold", type=float, required=True, help="Threshold (0.0-1.0, fraction of max magnitude)")
|
||||||
@click.option("--label", type=str, default=None, help="Annotation label")
|
@click.option("--label", type=str, default=None, help="Annotation label")
|
||||||
@click.option("--window-size", type=int, default=None, help="Smoothing window size in samples (default: 1ms at recording sample rate)")
|
@click.option(
|
||||||
|
"--window-size",
|
||||||
|
type=int,
|
||||||
|
default=None,
|
||||||
|
help="Smoothing window size in samples (default: 1ms at recording sample rate)",
|
||||||
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
"--type",
|
"--type",
|
||||||
"annotation_type",
|
"annotation_type",
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,12 @@ VISUALIZATION_TYPES = {
|
||||||
"spines",
|
"spines",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"annotations": {
|
"annotations": {
|
||||||
"function": view_annotations,
|
"function": view_annotations,
|
||||||
"description": "Annotation-focused spectrogram view",
|
"description": "Annotation-focused spectrogram view",
|
||||||
"options": ["channel", "dark"],
|
"options": ["channel", "dark"],
|
||||||
},
|
},
|
||||||
"channels": {"function": view_channels, "description": "Multi-channel IQ and spectrogram view", "options": []},
|
"channels": {"function": view_channels, "description": "Multi-channel IQ and spectrogram view", "options": []},
|
||||||
"annotations": {"function": view_annotations, "description": "Annotated spectrogram view", "options": ["channel", "dark"]},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user