TofuPilotTofuPilot

Multi-Dimensional

Record multi-dimensional data with axis validators and aggregations.

WiFi Enabled
True
x==True
Pass
Output Voltage
Pass
Output Voltage
5.02V
4.8<x<5.2
Pass

You can create a multi-dimensional measurement with measurements:

measurements:
  - name: Output Voltage
    multi_dimensional: 
      title: Output Voltage
      x_axis: 
        legend: Time
        unit: ms
      y_axis: 
        - legend: Voltage
          unit: V

You can set the measurement value in your Python phase:

def measure_voltage(run, measurements, dmm):
    times = []
    voltages = []

    for t in range(0, 201, 5):
        times.append(t)
        voltages.append(dmm.read_voltage())

    measurements.output_voltage = { 
        "x_axis": {"data": times}, 
        "y_axis": [{"data": voltages}] 
    } 

Definition

Measurement

You can configure the measurement name and metadata.

PropertyTypeRequiredDescription
keystringNoUnique identifier for the measurement within the phase
namestringYesDisplay name (1-100 characters)
descriptionstringNoDetailed description (max 50,000 characters)
multi_dimensionalobjectYesMulti-dimensional configuration

TofuPilot auto-generates the key from name (snake_case) if not specified, and uses it for Python access (e.g., measurements.frequency_response).

Multi-Dimensional

The multi_dimensional object defines the axes structure:

PropertyTypeRequiredDescription
titlestringNoChart title
x_axisobjectYesX-axis specification
y_axisarrayYesArray of Y-axis specifications (one or more)

Axis

Each axis (x_axis or y_axis item) has the following properties:

PropertyTypeRequiredDescription
legendstringNoAxis label for chart legend
unitstringNoAxis unit (e.g., "Hz", "V", "dB")
validatorsarrayNoValidators for axis data
aggregationsarrayNoAggregations for axis data (e.g., mean, max, min)

Validators

You can add validators to each axis to check individual data points.

y_axis:
  - legend: Voltage
    unit: V
    validators: 
      - operator: ">="
        expected_value: 0
      - operator: "<="
        expected_value: 5

TofuPilot will check each data point against the validators and set the outcome to Fail if any single 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.1

TofuPilot will compute the aggregation and validate the result. See Aggregations for available functions.

Examples

Multi-Channel Waveform

We will capture waveforms from multiple channels simultaneously:

phases:
  - name: Waveform Capture
    python:
      module: capture_waveform
    measurements:
      - name: Output Waveform
        description: Dual-channel oscilloscope capture
        multi_dimensional:
          title: Output Waveform
          x_axis:
            legend: Time
            unit: ms
          y_axis:
            - legend: Channel 1
              unit: V
            - legend: Channel 2
              unit: V
def capture_waveform(run, measurements, scope):
    log.info("Capturing waveform")

    scope.trigger()
    data = scope.get_waveform()

    times = data['time']
    ch1 = data['channel1']
    ch2 = data['channel2']

    measurements.output_waveform = {
        "x_axis": {"data": times},
        "y_axis": [
            {"data": ch1},
            {"data": ch2}
        ]
    }

    log.info(f"Captured {len(times)} samples")

Combining Validators and Aggregations

We will measure voltage over time and validate both individual readings and overall statistics:

phases:
  - name: Voltage Monitoring
    python:
      module: measure_voltage
    measurements:
      - name: Output Voltage
        description: Voltage monitoring with per-point and statistical validation
        multi_dimensional:
          title: Output Voltage
          x_axis:
            legend: Time
            unit: ms
          y_axis:
            - legend: Voltage
              unit: V
              validators:
                - operator: ">="
                  expected_value: 0
                - operator: "<="
                  expected_value: 5
              aggregations:
                - type: mean
                  validators:
                    - operator: ">="
                      expected_value: 2.9
                    - operator: "<="
                      expected_value: 3.1
def measure_voltage(run, measurements, 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": {"data": times},
        "y_axis": [{"data": voltages}]
    }

    log.info(f"Captured {len(times)} samples")

Validators ensure each reading is within physical limits (0-5V). Aggregations ensure overall statistical properties meet specifications (mean 2.9-3.1V). The measurement fails if any single point exceeds limits OR if the average is out of spec.

How is this guide?