Skip to content

Waveform

from cascaqit import Waveform

Waveform

Waveform(
    waveform_ir: WaveformIR,
    _value_templates: tuple[AnalogWaveformValue, ...]
    | None = None,
)

Describe an analog control over time. Usually start with constant(), linear() or a piecewise constructor; Waveform(waveform_ir) is useful when you already have IR. Constructors, bind() and concat() return new waveforms without modifying their inputs.

Time is in us; value_unit specifies amplitude units and defaults to rad/us. Use rad for phase waveforms. Numeric amplitudes must be finite and cannot be booleans. A Parameter or expression must have matching units. Construction alone does not establish target validity: check duration, sample times and target amplitude limits through program validation.

See Waveform design and Interpolated waveforms.

Constructing waveforms

constant

constant(
    value: AnalogWaveformValue,
    *,
    duration: float,
    waveform_id: str = "waveform",
    value_unit: str = "rad/us",
) -> Waveform

Hold value for duration. The value may be numeric, a parameter or an expression. Return Waveform; invalid numeric types, nonfinite values or unit mismatches raise TypeError or ValueError.

linear

linear(
    start: AnalogWaveformValue,
    stop: AnalogWaveformValue,
    *,
    duration: float,
    waveform_id: str = "waveform",
    value_unit: str = "rad/us",
) -> Waveform

Ramp from start to stop over duration. Endpoints may contain parameters; binding produces a numeric waveform.

piecewise_linear

piecewise_linear(
    *,
    times: Sequence[float],
    values: Sequence[AnalogWaveformValue],
    waveform_id: str = "waveform",
    value_unit: str = "rad/us",
) -> Waveform

Define a polygonal curve using equally sized times and values, with linear interpolation between adjacent points. The last time determines duration. Times should start at zero and increase strictly. Empty times or unequal lengths immediately raise ValueError; confirm the remaining time constraints through program validation.

piecewise_constant

piecewise_constant(
    *,
    times: Sequence[float],
    values: Sequence[AnalogWaveformValue],
    waveform_id: str = "waveform",
    value_unit: str = "rad/us",
) -> Waveform

Define a step waveform with equally sized times and values. Each interval uses its left endpoint's value. The current evaluator assigns a boundary time to the interval on its left: at the final time it still returns the preceding value, and only beyond it returns the final stored value. Thus values are supplied per boundary, not just per interval. The final time determines duration; empty times or unequal lengths raise ValueError.

interpolated

interpolated(
    *,
    times: Sequence[float],
    values: Sequence[AnalogWaveformValue],
    waveform_id: str = "waveform",
    value_unit: str = "rad/us",
) -> Waveform

Join samples using shape-preserving PCHIP interpolation. Supply at least two finite times starting at 0.0 and increasing strictly; invalid times immediately raise ValueError. Times and values must have equal lengths. Values may contain parameters. PCHIP controls overshoot but does not establish compliance with a target's bandwidth or slew limits.

parameter

parameter(
    name: str,
    *,
    duration: float,
    waveform_id: str = "waveform",
    value_unit: str = "rad/us",
    scale: float = 1.0,
    offset: float = 0.0,
) -> Waveform

Create a constant waveform with value scale * parameter_value + offset, referencing the parameter by name and lasting for duration. For new programs, prefer declaring a parameter with AHSProgram.parameter() and passing it to constant(). Named expressions must still match program declarations and units.

Binding and composition

bind

bind(values: Mapping[str, float]) -> Waveform

Evaluate a mapping of names to numeric values and return an independent waveform. Parameter declarations determine defaults and bounds. Usually call AHSProgram.bind() so that all waveforms and spatial weights use the same bindings.

concat

concat(
    *others: Waveform,
    waveform_id: str | None = None,
    max_points: int = 1024,
) -> Waveform

Append at least one waveform in time and return a new waveform whose duration is the sum of its segments. Segments must share units and a compatible family: constant/step or linear/piecewise linear. Linear segments must meet continuously; symbolic endpoints are compared as expressions.

PCHIP segments cannot be concatenated because refitting would change the original curves. Legacy named constant expressions must be bound first. max_points is an integer from 2 to 1024 limiting output sample points. Missing following segments, incompatible families, discontinuous seams or exceeding the limit produce errors.

to_ir

to_ir() -> WaveformIR

Return an independent numeric WaveformIR. Unbound values raise ProgramValidationError; export does not substitute placeholders.

Parameter inspection

is_bound

is_bound: bool

Return True when all amplitude values have been resolved to numbers.

is_parameter_reference

is_parameter_reference: bool

Report whether the waveform stores a canonical named expression. This is different from asking whether it contains any symbolic values; use is_bound to check whether numeric export is possible.

referenced_parameter_names

referenced_parameter_names: tuple[str, ...]

Return referenced parameter names as a tuple without duplicates. Ordinary parameter templates sort names; canonical expressions use their dependency order.

validate_parameter_references

validate_parameter_references(
    declarations: Mapping[str, Parameter],
) -> None

Check parameter ownership, names and units against declarations, returning None on success. A directly supplied Parameter must be the declaration object owned by the program; expression dependencies must exist in the declaration mapping. Mismatches raise ProgramValidationError. This does not check physical waveform limits against a target.