> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.conductorquantum.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.conductorquantum.com/_mcp/server.

# stanza.routines.builtins.health_check

Device health check routines for quantum dot devices operating in accumulation mode.

These routines are specifically designed for accumulation mode devices, where gates are
swept from depletion to accumulation to establish conductive channels. The algorithms
identify turn-on voltages where current begins to flow as gates transition from depleted
to accumulated states.

Voltage Bounds and Carrier Type Conventions
--------------------------------------------
The safe voltage bounds (max_safe_voltage_bound and min_safe_voltage_bound) represent the
extreme voltages that can be safely applied to gates without causing device damage or
unwanted leakage. The interpretation of these bounds depends on the charge carrier type:

For electron-based devices (n-channel, charge_carrier_type="electron"):
    - Accumulation occurs at POSITIVE gate voltages, which attract electrons to form
      a conductive channel
    - max_safe_voltage_bound is POSITIVE and represents the maximum safe positive voltage
    - min_safe_voltage_bound is NEGATIVE and represents the most negative voltage (depletion)
    - Current INCREASES as gate voltage sweeps from negative (depleted) to positive (accumulated)

For hole-based devices (p-channel, charge_carrier_type="hole"):
    - Accumulation occurs at NEGATIVE gate voltages, which attract holes to form
      a conductive channel
    - max_safe_voltage_bound is POSITIVE and represents the most positive voltage (depletion)
    - min_safe_voltage_bound is NEGATIVE and represents the maximum safe negative voltage
    - Current INCREASES as gate voltage sweeps from positive (depleted) to negative (accumulated)

In both cases, the routines sweep from depletion (low current) toward accumulation (high current),
but the voltage polarity is reversed between electron and hole devices. The charge_carrier_type
parameter determines which voltage bound is used for accumulation sweeps.

Health check tests are an improvement of:
    Kovach, T. et al. BATIS: Bootstrapping, Autonomous Testing, and
    Initialization System for Si/SiGe Multi-quantum Dot Devices. arXiv
    preprint arXiv:2412.07676 (2024). https://arxiv.org/abs/2412.07676

## Module Contents

### Functions

| Name | Description |
|------|-------------|
| [`noise_floor_measurement`](#stanzaroutinesbuiltinshealth_checknoise_floor_measurement) | Measure the noise floor of the device to establish baseline current measurement statistics. |
| [`leakage_test`](#stanzaroutinesbuiltinshealth_checkleakage_test) | Test for leakage between control gates by measuring inter-gate resistance across voltage ranges. |
| [`global_accumulation`](#stanzaroutinesbuiltinshealth_checkglobal_accumulation) | Determine the global turn-on voltage by sweeping all control gates simultaneously. |
| [`reservoir_characterization`](#stanzaroutinesbuiltinshealth_checkreservoir_characterization) | Characterize individual reservoir gates by sweeping each while holding others in accumulation. |
| [`finger_gate_characterization`](#stanzaroutinesbuiltinshealth_checkfinger_gate_characterization) | Characterize individual finger gates by sweeping each while holding others in accumulation. |
| [`_calculate_leakage_matrix`](#stanzaroutinesbuiltinshealth_check_calculate_leakage_matrix) | Calculate leakage resistance matrix from voltage change and current differences. |
| [`_check_leakage_threshold`](#stanzaroutinesbuiltinshealth_check_check_leakage_threshold) | Check if leakage matrix exceeds threshold and log if it does. |
| [`_test_single_voltage_bound`](#stanzaroutinesbuiltinshealth_check_test_single_voltage_bound) | Test for leakage at a single voltage bound by sweeping gates incrementally. |
| [`analyze_single_gate_heuristic`](#stanzaroutinesbuiltinshealth_checkanalyze_single_gate_heuristic) | Fit gate sweep data to extract cut-off voltage using a heuristic model. |

### Data

`logger`
`DEFAULT_SETTLING_TIME_S`

### API

```python
stanza.routines.builtins.health_check.logger
```

**Value**: `getLogger(...)`


```python
stanza.routines.builtins.health_check.DEFAULT_SETTLING_TIME_S
```

**Value**: `10`


```python
stanza.routines.builtins.health_check.noise_floor_measurement(
    ctx: stanza.routines.RoutineContext,
    measure_electrode: str,
    num_points: int = 100,
    session: stanza.logger.session.LoggerSession | None = None,
    **kwargs: typing.Any
) -> dict[str, float]
```

Measure the noise floor of the device to establish baseline current measurement statistics.

This routine performs repeated current measurements on a specified electrode to characterize
the measurement noise floor. The resulting mean and standard deviation are used to establish
minimum current thresholds for subsequent health check routines, helping to distinguish
real signals from measurement noise.

**Parameters:**

<ParamField path="ctx" type="stanza.routines.RoutineContext">
  Routine context containing device resources and previous results.
</ParamField>

<ParamField path="measure_electrode" type="str">
  Name of the electrode to measure current from.
</ParamField>

<ParamField path="num_points" type="int" default="100">
  Number of current measurements to collect for statistical analysis. Default is 100.
</ParamField>

<ParamField path="session" type="stanza.logger.session.LoggerSession | None">
  Optional logger session for recording measurements and analysis results.
</ParamField>

**Returns:**

dict: Contains:
- current_mean: Mean of measured currents (A)
- current_std: Standard deviation of measured currents (A)
Notes:
- All measurements are taken at the device's current voltage configuration
- Results are automatically logged to session if provided
- The current_std value is commonly used in leakage_test as min_current_threshold


```python
stanza.routines.builtins.health_check.leakage_test(
    ctx: stanza.routines.RoutineContext,
    leakage_threshold_resistance: int,
    leakage_threshold_count: int = 0,
    num_points: int = 10,
    session: stanza.logger.session.LoggerSession | None = None,
    **kwargs: typing.Any
) -> dict[str, float]
```

Test for leakage between control gates by measuring inter-gate resistance across voltage ranges.

This routine systematically tests for electrical leakage between all pairs of control gates
by sweeping each gate through its voltage range and measuring the current response on all
other gates. Leakage is quantified as resistance (dV/dI) between gate pairs. Gates with
resistance below the threshold indicate potential shorts or unwanted crosstalk.

The test sweeps both positive (max_voltage_bound) and negative (min_voltage_bound) directions
from the initial voltages to detect asymmetric leakage behavior. Both bounds are tested
independently, so failure at one bound does not prevent testing the other.

Note on voltage bounds: max_safe_voltage_bound is typically positive and min_safe_voltage_bound
is typically negative, representing the extreme safe operating voltages. For electron devices,
max (positive) is used for accumulation sweeps; for hole devices, min (negative) is used for
accumulation sweeps. See module-level docstring for detailed explanation.

**Parameters:**

<ParamField path="ctx" type="stanza.routines.RoutineContext">
  Routine context containing device resources. Uses ctx.results.get("current_std")
</ParamField>

<ParamField path="leakage_threshold_resistance" type="int">
  Maximum acceptable resistance (Ohms) between gate pairs.
</ParamField>

<ParamField path="leakage_threshold_count" type="int" default="0">
  Maximum number of leaky gate pairs allowed before failing the test.
</ParamField>

<ParamField path="num_points" type="int" default="10">
  Number of voltage steps to test in each direction. Default is 10.
</ParamField>

<ParamField path="session" type="stanza.logger.session.LoggerSession | None">
  Optional logger session for recording leakage matrices and analysis results.
</ParamField>

**Returns:**

dict: Contains the delta_V tested for each voltage bound:
- max_voltage_bound: The voltage offset tested for max bound (V)
- min_voltage_bound: The voltage offset tested for min bound (V)
If leakage exceeds threshold, returns the offset where it was first detected.
If no leakage detected, returns the final offset tested.

**Raises:**

Exception: Re-raises any exceptions encountered during testing after logging.
Notes:
- Device is always returned to initial voltages in the finally block
- Leakage matrix is symmetric, only upper triangle is checked
- Both voltage bounds are tested regardless of failures
- Current differences below min_current_threshold are skipped to avoid noise
- Voltage bounds are determined from device channel configurations


```python
stanza.routines.builtins.health_check.global_accumulation(
    ctx: stanza.routines.RoutineContext,
    measure_electrode: str,
    step_size: float,
    bias_gate: str,
    bias_voltage: float,
    charge_carrier_type: str,
    session: stanza.logger.session.LoggerSession | None = None,
    **kwargs: typing.Any
) -> dict[str, float]
```

Determine the global turn-on voltage by sweeping all control gates simultaneously.

This health check routine is specifically designed for accumulation mode devices.
It sweeps all control gates together from minimum to maximum voltage while measuring
current at a specified electrode. The sweep data is analyzed using a pinch-off heuristic
to identify the voltage at which the device transitions from depletion to accumulation
(turn-on). After finding this voltage, all gates are set to the cut-off voltage.

This global characterization establishes a baseline operating point before individual
gate characterization in subsequent routines.

**Parameters:**

<ParamField path="ctx" type="stanza.routines.RoutineContext">
  Routine context containing device resources and previous results. Requires
</ParamField>

<ParamField path="measure_electrode" type="str">
  Name of the electrode to measure current from during the sweep.
</ParamField>

<ParamField path="step_size" type="float">
  Voltage increment (V) between sweep points. Smaller values provide
</ParamField>

<ParamField path="charge_carrier_type" type="str">
  The mobile charge particle type. Must be "electron" or "hole".
</ParamField>

<ParamField path="session" type="stanza.logger.session.LoggerSession | None">
  Optional logger session for recording sweep measurements and analysis results.
</ParamField>

**Returns:**

dict: Contains:
- global_turn_on_voltage: The cut-off voltage (cutoff_voltage) where current begins to flow through the device (V)
Notes:
- All control gates are swept together (global sweep)
- Device is automatically set to cutoff_voltage after analysis
- The cutoff_voltage value is used by subsequent characterization routines (reservoir, finger gates)
- step_size is converted to num_points based on voltage range
- For electron devices: sweeps toward positive voltages (accumulation at positive V)
- For hole devices: sweeps toward negative voltages (accumulation at negative V)


```python
stanza.routines.builtins.health_check.reservoir_characterization(
    ctx: stanza.routines.RoutineContext,
    measure_electrode: str,
    step_size: float,
    bias_gate: str,
    bias_voltage: float,
    charge_carrier_type: str = 'electron',
    session: stanza.logger.session.LoggerSession | None = None,
    **kwargs: typing.Any
) -> dict[str, dict[str, typing.Any]]
```

Characterize individual reservoir gates by sweeping each while holding others in accumulation.

This health check routine is specifically designed for accumulation mode devices.
It determines the cut-off voltage (cutoff_voltage) for each reservoir gate individually.
For each reservoir under test, all other reservoirs are set to 120% of the global turn-on
voltage (to ensure they're fully conducting), while the target reservoir is swept from
minimum to maximum voltage. This isolates the behavior of each reservoir and identifies its
individual pinch-off characteristics.

**Parameters:**

<ParamField path="ctx" type="stanza.routines.RoutineContext">
  Routine context containing device resources and previous results. Requires:
</ParamField>

<ParamField path="measure_electrode" type="str">
  Name of the electrode to measure current from during sweeps.
</ParamField>

<ParamField path="step_size" type="float">
  Voltage increment (V) between sweep points. Smaller values provide
</ParamField>

<ParamField path="charge_carrier_type" type="str" default="'electron'">
  The mobile charge particle type. Must be "electron" or "hole". Default is "electron".
</ParamField>

<ParamField path="session" type="stanza.logger.session.LoggerSession | None">
  Optional logger session for recording sweep measurements and analysis results.
</ParamField>

**Returns:**

dict: Contains:
- reservoir_characterization: Dictionary mapping each reservoir name to its
cut-off voltage (cutoff_voltage) in volts.
Notes:
- Each reservoir is tested sequentially
- Other reservoirs are biased at min(1.2 * global_turn_on_voltage, max_voltage_bound)
- Target reservoir starts at 0V before sweeping
- 10 second settling time is used between voltage changes
- Pinch-off analysis may raise ValueError if curve fit fails
- Sweep direction depends on carrier type: electrons sweep toward positive, holes toward negative


```python
stanza.routines.builtins.health_check.finger_gate_characterization(
    ctx: stanza.routines.RoutineContext,
    measure_electrode: str,
    step_size: float,
    bias_gate: str,
    bias_voltage: float,
    charge_carrier_type: str = 'electron',
    session: stanza.logger.session.LoggerSession | None = None,
    **kwargs: typing.Any
) -> dict[str, dict[str, typing.Any]]
```

Characterize individual finger gates by sweeping each while holding others in accumulation.

This health check routine is specifically designed for accumulation mode devices.
It determines the cut-off voltage for each finger gate individually. For each finger gate
under test, all other finger gates are set to 120% of the global turn-on voltage (to ensure
they're fully accumulated), while the target gate is swept from minimum to maximum voltage.
This isolates the behavior of each finger gate and identifies its individual pinch-off
characteristics.

**Parameters:**

<ParamField path="ctx" type="stanza.routines.RoutineContext">
  Routine context containing device resources and previous results. Requires:
</ParamField>

<ParamField path="measure_electrode" type="str">
  Name of the electrode to measure current from during sweeps.
</ParamField>

<ParamField path="step_size" type="float">
  Voltage increment (V) between sweep points. Smaller values provide
</ParamField>

<ParamField path="charge_carrier_type" type="str" default="'electron'">
  The mobile charge particle type. Must be "electron" or "hole". Default is "electron".
</ParamField>

<ParamField path="session" type="stanza.logger.session.LoggerSession | None">
  Optional logger session for recording sweep measurements and analysis results.
</ParamField>

**Returns:**

dict: Contains:
- finger_gate_characterization: Dictionary mapping each finger gate name to its
cut-off voltage (cutoff_voltage) in volts.
Notes:
- Each finger gate is tested sequentially
- Other finger gates are biased at min(1.2 * global_turn_on_voltage, max_voltage_bound)
- Target gate starts at voltage_left_bound before sweeping
- 10 second settling time is used after setting target gate to voltage_left_bound
- Pinch-off analysis may raise ValueError if curve fit fails
- Sweep direction depends on carrier type: electrons sweep toward positive, holes toward negative


```python
stanza.routines.builtins.health_check._calculate_leakage_matrix(
    delta_V: float, current_diff: numpy.ndarray
) -> numpy.ndarray
```

Calculate leakage resistance matrix from voltage change and current differences.

**Parameters:**

<ParamField path="delta_V" type="float">
  Voltage change applied (V).
</ParamField>

<ParamField path="current_diff" type="numpy.ndarray">
  Array of current differences for each gate (A).
</ParamField>

**Returns:**

Leakage resistance matrix (Ohms) where leakage_matrix[i,j] = |delta_V / (I_j - I_j_prev)|
when gate i was swept. Inf values indicate no measurable current change.


```python
stanza.routines.builtins.health_check._check_leakage_threshold(
    leakage_matrix: numpy.ndarray,
    leakage_threshold_resistance: int,
    leakage_threshold_count: int,
    control_gates: list[str],
    delta_V: float,
    session: stanza.logger.session.LoggerSession | None
) -> bool
```

Check if leakage matrix exceeds threshold and log if it does.

**Parameters:**

<ParamField path="leakage_matrix" type="numpy.ndarray">
  Resistance matrix between gate pairs (Ohms).
</ParamField>

<ParamField path="leakage_threshold_resistance" type="int">
  Maximum acceptable resistance threshold (Ohms).
</ParamField>

<ParamField path="leakage_threshold_count" type="int">
  Maximum number of leaky gate pairs allowed.
</ParamField>

<ParamField path="control_gates" type="list[str]">
  List of control gate names for reporting.
</ParamField>

<ParamField path="delta_V" type="float">
  Current voltage offset being tested (V).
</ParamField>

<ParamField path="session" type="stanza.logger.session.LoggerSession | None">
  Optional logger session for recording leakage analysis.
</ParamField>

**Returns:**

True if leakage threshold is exceeded, False otherwise.


```python
stanza.routines.builtins.health_check._test_single_voltage_bound(
    ctx: stanza.routines.RoutineContext,
    voltage_bound: float,
    control_gates: list[str],
    initial_voltages: list[float],
    initial_currents: list[float],
    leakage_threshold_resistance: int,
    leakage_threshold_count: int,
    min_current_threshold: float,
    num_points: int,
    session: stanza.logger.session.LoggerSession | None
) -> tuple[float, bool]
```

Test for leakage at a single voltage bound by sweeping gates incrementally.

**Parameters:**

<ParamField path="ctx" type="stanza.routines.RoutineContext">
  Routine context containing device resources.
</ParamField>

<ParamField path="voltage_bound" type="float">
  Target voltage bound to test (V).
</ParamField>

<ParamField path="control_gates" type="list[str]">
  List of control gate names to test.
</ParamField>

<ParamField path="initial_voltages" type="list[float]">
  Initial voltage for each gate (V).
</ParamField>

<ParamField path="initial_currents" type="list[float]">
  Initial current for each gate (A).
</ParamField>

<ParamField path="leakage_threshold_resistance" type="int">
  Maximum acceptable resistance between gates (Ohms).
</ParamField>

<ParamField path="leakage_threshold_count" type="int">
  Maximum number of leaky gate pairs allowed.
</ParamField>

<ParamField path="min_current_threshold" type="float">
  Minimum current change to consider for resistance calculation (A).
</ParamField>

<ParamField path="num_points" type="int">
  Number of voltage steps to test.
</ParamField>

<ParamField path="session" type="stanza.logger.session.LoggerSession | None">
  Optional logger session for recording measurements.
</ParamField>

**Returns:**

Tuple of (delta_V, leaked) where:
- delta_V: The voltage offset tested (V). If leakage detected, the offset where it occurred.
- leaked: True if leakage threshold was exceeded, False otherwise.


```python
stanza.routines.builtins.health_check.analyze_single_gate_heuristic(
    voltages: numpy.ndarray, currents: numpy.ndarray
) -> dict[str, typing.Any]
```

Fit gate sweep data to extract cut-off voltage using a heuristic model.

This analysis function is specifically designed for accumulation mode devices,
where the sweep progresses from depletion to accumulation and the algorithm
identifies the cut-off voltage at which current begins to flow.

**Parameters:**

<ParamField path="voltages" type="numpy.ndarray">
  Array of gate voltages (V) from the sweep.
</ParamField>

<ParamField path="currents" type="numpy.ndarray">
  Array of measured currents (A) corresponding to each voltage.
</ParamField>

**Returns:**

dict: Contains cutoff_voltage (cut-off voltage) and other fit parameters.

**Raises:**

ValueError: If the curve fit quality is poor based on R² and NRMSE metrics.