Vector Sink
Der Gegenpart zum Vector Source — sammelt einen Datenstrom vollständig als Python-Array, ohne eine GUI-Anzeige zu benötigen.
1. Beschreibung des Blocks
Der Vector Sink-Block (blocks.vector_sink_x) sammelt alle bei ihm ankommenden Samples in einem internen Puffer, statt sie darzustellen oder weiterzuleiten. Er hat keine grafische Oberfläche und keinen Ausgang — der Zugriff auf die gesammelten Werte erfolgt ausschließlich über seine Python-API, per data() für die Samples selbst und tags() für alle mitgelaufenen Stream-Tags.
Er ist damit das exakte Gegenstück zum Vector Source-Block: Wo Vector Source einen festen, bekannten Datensatz in den Flowgraph einspeist, sammelt Vector Sink das Ergebnis der Verarbeitung wieder ein — beide zusammen bilden den Standardaufbau für reproduzierbare, headless durchführbare Tests.
2. Technischer Einsatz
assert gegen einen vorher berechneten Erwartungswert (Ground Truth) geprüft — vollständig automatisiert und ohne geöffnetes GUI-Fenster ausführbar.Typischer Testaufbau: vector_source (Testsignal mit bekanntem Inhalt) → zu testender Block → vector_sink (Ergebnis einsammeln) → tb.run() → assert auf snk.data(). Dieses Muster wird im BCD-Decoder-Test und im FSK/RTTY-Test durchgängig verwendet.
3. Parameter und Dimensionierung
| Parameter | Typ/Einheit | Bedeutung | Dimensionierungshinweis |
|---|---|---|---|
type (Input Type) |
Enum | Datentyp: Complex, Float, Int, Short, Byte | muss zum Ausgangstyp des vorgeschalteten Blocks passen |
vlen (Vector Length) |
Integer | Anzahl Elemente pro Vektor-Sample | Standard 1 (Skalarstrom) |
reserve_items (Reserve memory for items) |
Integer | Vorab reservierte Puffergröße | reine Performance-Optimierung gegen wiederholtes Reallozieren bei großen Captures — kein hartes Limit, siehe unten |
reserve_items tatsächlich nur ein Performance-Hinweis oder doch eine harte Kapazitätsgrenze ist, wurde bewusst mehr hineingeschickt, als reserviert wurde:
from gnuradio import gr, blocks
tb = gr.top_block()
data = list(range(2000)) # 2000 Samples ...
src = blocks.vector_source_f([float(x) for x in data], False)
snk = blocks.vector_sink_f(1, 100) # ... aber nur reserve_items=100
tb.connect(src, snk)
tb.run()
print("captured length:", len(snk.data()))
from gnuradio import gr, blocks
tb = gr.top_block()
data = list(range(2000)) # 2000 Samples ...
src = blocks.vector_source_f([float(x) for x in data], False)
snk = blocks.vector_sink_f(1, 100) # ... aber nur reserve_items=100
tb.connect(src, snk)
tb.run()
print("captured length:", len(snk.data()))
Ausgabe:
captured length: 2000
captured length: 2000
Warum dieser Test: Wäre reserve_items eine harte Grenze, würde der Vector Sink entweder abstürzen oder die Aufnahme bei 100 Samples abschneiden. Da tatsächlich alle 2000 Samples ankommen, ist bestätigt: Der Parameter reserviert nur vorab Speicher zur Vermeidung wiederholter Reallokation — der Puffer wächst bei Bedarf automatisch darüber hinaus, ohne Datenverlust.
4. Ein- und Ausgänge
| Ein-/Ausgang | Typ |
|---|---|
| Eingang | Complex, Float, Int, Short oder Byte (je nach type) |
| Ausgang | keiner |
5. Weitere wichtige Aspekte
Zugriff auf die gesammelten Daten: Nach tb.run() liefert snk.data() alle empfangenen Samples als Python-Liste (bei Complex als complex-Werte, ansonsten als float/int). snk.tags() liefert zusätzlich alle mitgelaufenen Stream-Tags mit ihrer jeweiligen Sample-Position — wichtig, um z. B. beim BCD-Decoder-Test geprüfte Bit-Tags exakt zu lokalisieren.
from gnuradio import gr, blocks
tb = gr.top_block()
src = blocks.vector_source_f([1.0, 2.0, 3.0, 4.0], False)
snk = blocks.vector_sink_f()
tb.connect(src, snk)
tb.run()
print("data():", snk.data())
from gnuradio import gr, blocks
tb = gr.top_block()
src = blocks.vector_source_f([1.0, 2.0, 3.0, 4.0], False)
snk = blocks.vector_sink_f()
tb.connect(src, snk)
tb.run()
print("data():", snk.data())
Ausgabe:
data(): [1.0, 2.0, 3.0, 4.0]
data(): [1.0, 2.0, 3.0, 4.0]
Warum diese Werte: Vier unterschiedliche, streng aufsteigende Zahlen wurden bewusst gewählt, weil damit sowohl eine Vertauschung der Reihenfolge als auch ein Verlust einzelner Samples sofort auffallen würde — ein Testdatensatz aus lauter gleichen Werten (z. B. Nullen) hätte einen solchen Fehler nicht sichtbar gemacht. Ausgabe und Eingabe sind identisch: keine Reihenfolgeänderung, kein Sample-Verlust.
Kein Ersatz für eine Anzeige während der Entwicklung: Vector Sink liefert kein visuelles Feedback — für die interaktive Fehlersuche im laufenden Betrieb ist zunächst weiterhin ein QT GUI Time Sink sinnvoller; Vector Sink kommt typischerweise erst zum Einsatz, wenn ein Testfall bereits feststeht und automatisiert wiederholbar sein soll.