Multi-Dimensional
Record multi-dimensional measurement data with axis validators and aggregations for complex sensor and signal analysis in TofuPilot.
You can create a multi-dimensional measurement with measurements:
measurements:
- name: Output Voltage
title: Output Voltage
x_axis:
legend: Time
unit: ms
y_axis:
- legend: Voltage
unit: VYou can set the measurement value in your Python phase using the builder pattern:
def measure_voltage(measurements, dmm):
times = []
voltages = []
for t in range(0, 201, 5):
times.append(t)
voltages.append(dmm.read_voltage())
measurements.output_voltage.x_axis = times
measurements.output_voltage.y_axis.voltage = voltages Definition
Measurement
You can configure the measurement name and metadata.
| Property | Type | Required | Description |
|---|---|---|---|
key | string | No | Unique identifier for the measurement within the phase |
name | string | Yes | Display name (1-100 characters) |
description | string | No | Detailed description (max 50,000 characters) |
title | string | No | Chart title |
x_axis | object | Yes | X-axis specification |
y_axis | array | Yes | Array of Y-axis specifications (one or more) |
TofuPilot auto-generates the key from name (snake_case) if not specified, and uses it for Python access (e.g., measurements.frequency_response).
Axis
Each axis (x_axis or y_axis item) has the following properties:
| Property | Type | Required | Description |
|---|---|---|---|
key | string | No | Python identifier for axis (auto-generated from legend if not set) |
legend | string | No | Axis label for chart legend |
unit | string | No | Axis unit (e.g., "Hz", "V", "dB") |
description | string | No | Axis description |
validators | array | No | Validators for axis data |
aggregations | array | No | Aggregations for axis data |
Validators
You can add validators to each axis to check individual data points.
y_axis:
- legend: Voltage
unit: V
validators:
- operator: "=="
expected_value: [3.0, 3.1, 3.0, 3.1] Axis validators only support the == and != operators with an array of expected values matching the data length. TofuPilot will compare each data point against the corresponding expected value and set the outcome to Fail if any point fails.
Aggregations
You can add aggregations to each axis to validate statistical properties.
y_axis:
- legend: Voltage
unit: V
aggregations:
- type: mean
validators:
- operator: ">="
expected_value: 2.9
- operator: "<="
expected_value: 3.1TofuPilot will validate the aggregation value against the specified criteria. You must set the aggregation value from Python. See Aggregations for details.
Examples
Multi-Channel Waveform
We will capture waveforms from multiple channels simultaneously:
main:
- name: Waveform Capture
python: capture_waveform
measurements:
- name: Output Waveform
description: Dual-channel oscilloscope capture
title: Output Waveform
x_axis:
legend: Time
unit: ms
y_axis:
- legend: Channel 1
key: channel_1
unit: V
- legend: Channel 2
key: channel_2
unit: Vdef capture_waveform(measurements, log, scope):
log.info("Capturing waveform")
scope.trigger()
data = scope.get_waveform()
measurements.output_waveform.x_axis = data['time']
measurements.output_waveform.y_axis.channel_1 = data['channel1']
measurements.output_waveform.y_axis.channel_2 = data['channel2']
log.info(f"Captured {len(data['time'])} samples")Combining Validators and Aggregations
We will measure voltage over time and validate both individual readings and overall statistics:
main:
- name: Voltage Monitoring
python: measure_voltage
measurements:
- name: Output Voltage
description: Voltage monitoring with range and statistical validation
title: Output Voltage
x_axis:
legend: Time
unit: ms
y_axis:
- legend: Voltage
unit: V
aggregations:
- type: min
validators:
- operator: ">="
expected_value: 0
- type: max
validators:
- operator: "<="
expected_value: 5
- type: mean
validators:
- operator: ">="
expected_value: 2.9
- operator: "<="
expected_value: 3.1def measure_voltage(measurements, log, dmm):
log.info("Monitoring voltage over time")
times = []
voltages = []
for t in range(0, 201, 5):
times.append(t)
voltages.append(dmm.read_voltage())
measurements.output_voltage.x_axis = times
measurements.output_voltage.y_axis.voltage = voltages
aggs = measurements.output_voltage.y_axis.voltage.aggregations
aggs.min = min(voltages)
aggs.max = max(voltages)
aggs.mean = sum(voltages) / len(voltages)
log.info(f"Captured {len(times)} samples")Range validation (0-5V) is done via min/max aggregations since axis validators only support == and !=. The mean aggregation validates overall statistics (2.9-3.1V). The measurement fails if any aggregation validator fails.
How is this guide?