rfgen.labels¶
Reference surface for the labelers: metadata-only bbox labeling, grid segmentation labeling, and a joint labeler that produces both.
A labeler returns a LabelSet — what it derived, and nothing it was handed.
Every shipped labeler derives its labels from declared emitter metadata — carrier, bandwidth, on-time — and never from the composed samples. That is what makes a label usable as ground truth: it states what the generator put into the scene, not what a transform found afterwards.
Package layout¶
Module |
Holds |
|---|---|
|
|
|
the three labelers’ constructor-parameter models |
|
converting emitter-frame facts into the frame of the receiver that heard them |
|
rasterizing receiver-frame boxes onto a time-frequency grid |
|
|
|
encoding boxes as typed observation fields, with the frame they are in |
|
resolving a configured labeler name to its class, and building it |
|
|
|
|
|
Module summary¶
from rfgen.labels import JointLabeler
labels = JointLabeler(seg_n_fft=1024, seg_hop=256).label(
iq=scene_iq,
emitters=component_metadata,
scene=scene_metadata,
)
assert labels.bboxes
assert labels.segmentation is not None
TorchSig interop¶
Conversion lives in rfgen.integrations.torchsig.interop and is imported from
there:
Export |
Purpose |
|---|---|
|
Convert one single-receiver LabeledScene to a TorchSig 2.1 |
|
Convert a TorchSig |
See TorchSig interop for the shape contract and what does not survive the round trip.
Class index¶
Class |
Kind |
Notes |
|---|---|---|
abc |
Common pure-function contract for all labelers. |
|
concrete |
Derives one receiver-frame bbox per emitter from metadata only. |
|
concrete |
Rasterizes occupancy onto a time-frequency grid. |
|
concrete |
Returns a LabelSet carrying both boxes and a raster. |
class rfgen.labels.BaseLabeler¶
Abstract base class for shipped and plugin labelers.
class BaseLabeler(ABC):
name: ClassVar[str]
@abstractmethod
def label(
self,
iq: torch.Tensor,
emitters: tuple[SignalMetadata, ...],
scene: SceneMetadata,
) -> LabelSet: ...
@classmethod
@abstractmethod
def schema(cls) -> type[BaseModel]: ...
@classmethod
def from_config(cls, config: LabelConfig) -> Self: ...
Notes¶
label(...)is the runtime contract. The shipped labelers are pure functions of(iq, emitters, scene).schema()returns the Pydantic constructor schema used by config-driven construction.from_config(...)resolves the configured primary labeler throughrfgen.labelers.
Method: label¶
def label(
self,
iq: torch.Tensor,
emitters: tuple[SignalMetadata, ...],
scene: SceneMetadata,
) -> LabelSet: ...
Runtime labeler contract. An implementation returns a LabelSet carrying only what it derived.
iq is a shape and device contract, not a source of labels: every shipped
labeler derives occupancy from declared metadata. A labeler that needs no
tensor may accept None.
class rfgen.labels.BBoxLabeler¶
Metadata-only bbox derivation.
BBoxLabeler()
Method: label¶
def label(
self,
iq: torch.Tensor | None = None,
emitters: tuple[SignalMetadata, ...] | None = None,
scene: SceneMetadata | None = None,
) -> LabelSet
Behavior¶
Does not inspect
iq.Returns one BBox per emitter, in emitter order.
Resolves bbox frequency bounds in the active receiver frame from
scene.extras.Rejects unresolved joint multi-RX scenes when receiver center frequencies are heterogeneous, because one record’s box list can only describe one receiver frequency frame.
Raises LabelError on invalid bandwidth, invalid duration, negative start sample, missing receiver center frequency, or bboxes that escape the capture window.
class rfgen.labels.SegmentationLabeler¶
Time-frequency grid occupancy rasterization.
SegmentationLabeler(
*,
seg_n_fft: int = 1024,
seg_hop: int = 256,
mode: SegmentationMode = SegmentationMode.SINGLE_LABEL,
tie_break: SegmentationTieBreak = SegmentationTieBreak.LOWER_EMITTER_INDEX,
)
Method: label¶
def label(
self,
iq: torch.Tensor,
emitters: tuple[SignalMetadata, ...],
scene: SceneMetadata,
) -> LabelSet
Behavior¶
Requires
iq.Uses BBoxLabeler to derive the metadata bbox list first, then rasterizes those bboxes.
Uses
iqonly to validate rank and capture length, preserve the receiver axis for an unresolved multi-receiver scene, and place the output on the input device. Occupancy is not inferred from IQ amplitude or STFT energy.Resolves the active receiver sample rate from
scene.extras["receivers"][scene.rx_index]["sample_rate_hz"],scene.extras["rx_sample_rate_hz"], or the emitter metadata fallback.Single-label mode returns
torch.int16shape[F, T]with-1for background andclass_idfor occupied cells.Multi-label mode returns
torch.uint8shape[C, F, T], one binary plane per distinct class in sortedclass_idorder. Emitters with the same class share the same plane.tie_break=LOWER_EMITTER_INDEXis the shipped single-label overlap rule.
class rfgen.labels.JointLabeler¶
Default shipped labeler.
JointLabeler(
*,
seg_n_fft: int = 1024,
seg_hop: int = 256,
segmentation_mode: SegmentationMode = SegmentationMode.SINGLE_LABEL,
segmentation_tie_break: SegmentationTieBreak = SegmentationTieBreak.LOWER_EMITTER_INDEX,
)
Method: label¶
def label(
self,
iq: torch.Tensor,
emitters: tuple[SignalMetadata, ...],
scene: SceneMetadata,
) -> LabelSet
Behavior¶
Requires
len(emitters) == scene.num_emitters.Requires
iq.Reuses the shipped BBoxLabeler and SegmentationLabeler implementations so the two modalities stay aligned.
Rejects unresolved joint multi-RX scenes when
scene.extras["receivers"]carries heterogeneouscenter_freq_hzvalues, because one record’s box list cannot represent several receiver frequency frames safely.Returns a
LabelSetwhosebboxesstay parallel to the emitters it was given.
rfgen.labels.registry.build_labeler_suite¶
def build_labeler_suite(
config: LabelConfig,
) -> tuple[BaseLabeler, tuple[BaseLabeler, ...]]
Builds the configured primary labeler plus any extra_labelers, applying the
shared seg_n_fft, seg_hop, segmentation_mode, and
segmentation_tie_break defaults where the target labeler supports them.
class rfgen.labels.LabelSet¶
@dataclass(frozen=True, slots=True)
class LabelSet:
bboxes: tuple[BBox, ...] = ()
segmentation: torch.Tensor | None = None
def observation_fields(
self,
*,
receiver_center_hz: float,
sample_rate_hz: float,
class_names: Mapping[int, str] | None = None,
) -> dict[str, BaseObservationField]: ...
What a labeler derived. It replaces the Record earlier versions returned,
which carried back the IQ, scene, and emitters the labeler had just been given
— a bbox-only labeler had to fabricate a tensor it never read to satisfy that
return type.
observation_fields() encodes the clock-free labels as the two typed fields a
projection publishes, labels/boxes/extent and labels/boxes/identity. Both
frame arguments are required, with no defaults, so a labeler cannot publish
frequency edges without saying what they are offsets from. See Label
Schema.
The segmentation raster stays a tensor rather than becoming a field here: giving it coordinates needs the capture’s sample rate, time reference, origin, and per-receiver frames, none of which a labeler is given. The projection places it.
class rfgen.labels.LabeledScene¶
@dataclass(frozen=True, slots=True)
class LabeledScene:
iq: torch.Tensor
scene: SceneMetadata
emitters: tuple[SignalMetadata, ...]
labels: LabelSet = LabelSet()
One composed scene and the labels derived from it — the in-flight value that
travels from composition to projection, and what
generate_record
returns. It is
not a stored record: no schema_version, because that is a storage format’s
concern, and no text, because annotation is published as a snapshot’s own
annotation set.
Writing a labeler¶
Register the class under rfgen.labelers and return a LabelSet:
class MyLabeler(BaseLabeler):
name: ClassVar[str] = "mine"
@classmethod
def schema(cls) -> type[BaseModel]:
return MyParams
def label(self, iq, emitters, scene) -> LabelSet:
return LabelSet(bboxes=my_boxes(emitters, scene))
Returning a Record was the contract until the legacy record path was
retired, and no longer type-checks.
See Also¶
Reference / Label Schema: mask shapes, dtype rules, and bbox semantics.
Concepts / Labels: design rationale and modality boundaries.
LabelConfig: config-driven labeler construction.