Concatenate

Shipping
concat

Join 2–4 Signals or Vectors end-to-end along axis 0, rebuilding a monotonic time axis

Signature

Inputs

  • aSignal|VectorrequiredFirst segment. Locks the shape family (all Signals or all Vectors) and the unit for the whole join.
  • bSignal|VectorrequiredSecond segment. Must match `a`'s shape family and unit.
  • cSignal|VectorOptional third segment. Unwired ports are skipped; order follows port index a→b→c→d.
  • dSignal|VectorOptional fourth segment.

Outputs

  • resultSignal|VectorThe concatenated Signal (or Vector), values appended in port order.

Parameters

KeyTypeDefaultNotes
retimebooltrueHow the result's time axis is built (Signals only; ignored for Vectors). ON regenerates a clean UNIFORM axis from the FIRST input's sample rate anchored at its start ($t_i = t_0 + i/F_s$). OFF keeps each segment's OWN timestamps but shifts every later segment to start just after the previous one ends, preserving intra-segment spacing while keeping the axis strictly increasing.

Description

Concatenate joins 2–4 inputs end-to-end into one longer output (numpy np.concatenate([a, b, c, d]), axis 0). It accepts Signals or Vectors with two guard rails:

  • all wired inputs must be the SAME shape family — mixing a Signal with a Vector is a type error;
  • all wired inputs must carry the same unit string, else a type error. Concatenation does NOT convert, so joining V and A — or even m and cm — is rejected rather than silently relabelled/rescaled at the wrong scale.

Concatenation is a pure reindexing — every output sample IS an input sample, copied verbatim. Values are appended in port order (unwired optional ports skipped). Variances (σ²) are appended by the same map: σ is None only when every input is None; if ANY input carries σ², the exact ones contribute so the σ² array stays parallel to values (never a fabricated non-zero σ). Unit is preserved (all inputs share it). Timestamps are rebuilt to stay strictly monotonic, governed by retime: ON regenerates a uniform axis from the first input's ; OFF keeps each segment's raw timestamps but shifts each later segment so it starts just past the previous segment's last sample (). The result's sample_rate is the FIRST segment's (the time-base anchor). Vectors carry no time axis, so retime is inert on the Vector path.

Mathematics

Examples

Append two signals

a = [1,2] @100Hz (V), b = [3,4,5] @100Hz (V) → values [1,2,3,4,5], unit V, . With retime=true the axis is a single continuous .

Retime OFF keeps raw spacing

Two segments each with timestamps 0, .1. retime=false keeps the first verbatim (0, .1) and shifts the second one dt past → .2, .3, so the seam stays strictly increasing while intra-segment spacing is preserved.

Exact + uncertain join

One input has σ² [0.5, 0.5], the other is exact. The output σ² materialises as [0.5, 0.5, 0.0, 0.0] — the exact segment contributes zeros, never a fabricated value.

Applications

  • Stitching contiguous acquisition captures into one continuous record (retime ON).
  • Appending a pre-roll or trailer segment onto a signal while preserving each part's own timing (retime OFF).
  • Building a longer composite Vector from several computed sub-vectors sharing a unit.
  • Assembling a multi-phase test sequence (ramp, hold, sweep) into a single downstream stream.

Neat

Unit equality is enforced on the exact symbol, not the dimension: `m` + `cm` is rejected because concat never rescales, so silently joining at the wrong scale is impossible.

σ² allocation is lazy — an all-exact pipeline allocates no variance array at all; the moment any input is uncertain, exact segments back-fill with 0.0 to keep the array parallel.

The two `retime` strategies both guarantee a strictly-monotonic axis: a time coordinate must never go backwards across the seam.

Known issues

Only up to four inputs are supported (ports a–d); larger fan-ins must be chained through multiple concat nodes.

Different-unit inputs (including same-dimension `m`/`cm`) are hard-rejected rather than converted — convert upstream with `unit_convert` first.

Only 1-D arrays take the Vector path; higher-rank Arrays are a shape error (use `tensor_concat` for N-D).

See also

concatconcatenatejoinappendnumpyreindexing