Zip (Build Signal)
Shippingzip_signalFuse an X array and a Y array into one Signal (X→timestamps, Y→values), σ optional
Signature
Inputs
xVector|Signal— X / time axis. Absent ⇒ synthesized from sample_rate, or inherited from a Signal y.yVector|Signalrequired— The values (the data column). A Vector promotes to a Signal; a Signal's own values are used.sigmaVector|Signal— Per-sample standard deviation σ. Stored as variance σ²; overrides any uncertainty y carried.
Outputs
signalSignal— The fused Signal with timestamps = X, values = Y, and optional per-sample variance.
Parameters
| Key | Type | Default | Notes |
|---|---|---|---|
unit | text | Physical unit of the output values (the Y axis). Empty = inherit from the Y input. | |
sample_rate | float | 0Hz | Fs stamped on the output. 0 = auto: inferred from X spacing when uniform (best-effort average otherwise), and used to synthesize the axis when no X is wired. |
on_mismatch | enum | error | one of: error, truncate |
sort_by_x | boolean | false | Reorder samples by ascending X before building the Signal, turning scattered (X, Y) pairs into a monotonic axis. Y and σ follow their X. |
Description
Zip is the Build XY primitive: it takes an X array and a Y array and fuses them into one Signal whose timestamps = X and values = Y — the exact inverse of Unzip (unzip_signal). Because a Signal is stored structure-of-arrays (two parallel Vec<f64>, [[t…],[y…]]), this is a cheap, lossless interleave of two columns.
Each input accepts a Vector (a bare 1-D array) or a Signal (its values are taken as the array), making the node dual-purpose:
- wire X + Y → a non-uniformly-sampled signal with a custom axis;
- wire only Y (Vector) → promote a bare array to a Signal on a synthesized uniform axis;
- wire only Y (Signal) → keep that signal's own timestamps (a relabel).
Uncertainty rides along losslessly: a wired sigma (σ) is stored as variance and overrides any uncertainty y already carried; otherwise a Signal-y's own variances are preserved. When sample_rate = 0, Fs is inferred from the X spacing (exact when uniform, an average across the span otherwise). Length reconciliation follows on_mismatch: error refuses, truncate keeps the shortest. With sort_by_x on, samples are reordered by ascending X — and Y and σ² are permuted by the same index map so uncertainty stays parallel to the data. The node is stateless.
Mathematics
Examples
Build a signal from measured X and Y
Wire time array s into x and V into y. With sample_rate = 0, Zip infers a uniform axis and stamps Hz. The signal output inherits the V unit from Y.
Promote a bare array with uncertainty
Leave x unwired, feed a Vector into y and a σ Vector into sigma. Zip synthesizes an index axis (at the given sample_rate, default ) and stores as the signal's variance.
Scattered pairs into a monotonic axis
With X , Y , σ and sort_by_x = true, the output has X , Y and σ² — Y and σ² followed X through the sort.
Applications
- Building a non-uniformly-sampled signal from a measured time column and value column (LabVIEW Build XY).
- Promoting a computed 1-D array into a first-class Signal with an explicit sample rate and unit.
- Reordering scattered (X, Y) scatter data into a monotonic time series while carrying per-point error bars.
- Re-attaching per-sample uncertainty to a value stream by wiring a separately computed σ array.
Neat
σ is stored internally as variance (σ²), not σ — so a wired sigma is squared on ingest and truncation / sort permute the σ² array by the SAME index map as the values, keeping uncertainty length-locked to the data.
Fs inference is spacing-aware: a uniform axis yields the exact 1/Δt (within a 1e-6 relative tolerance), while a non-uniform axis falls back to the average rate across the span.
The X port is polymorphic — feeding it a Signal takes that signal's values as the axis, which is how 'only-Y-Signal' inherits its own timestamps.
Known issues
By default a length mismatch across X / Y / σ is a hard error; set on_mismatch = truncate to opt into shortest-wins behavior.
sort_by_x uses a partial comparison that treats NaN X values as equal (no reordering), so a NaN in the axis can leave points unsorted.
With no X and a Vector Y, the synthesized axis uses sample_rate (default 1 Hz) — the resulting timestamps are indices/Fs, not real measurement times.