nibcq.measurement.ParallelMeasurement
- class nibcq.measurement.ParallelMeasurement(leader: nibcq._device.Device, followers: collections.abc.Sequence[nibcq._device.Device], test_parameters: TestParameters)
Bases:
MeasurementAbstract parallel measurement workflow for any kind of measurement.
- Parameters:
leader (nibcq._device.Device)
followers (collections.abc.Sequence[nibcq._device.Device])
test_parameters (TestParameters)
- get_all_devices()
Yield every parallel device, followers first, leader last.
This generator avoids storing a redundant copy of the device references that already live in
ParallelMeasurement’s fields containing the followers and the leader.- Yields:
Device – The next device in followers-then-leader order.
- property all_measurement_data: collections.abc.Iterator[tuple[nibcq._device.Device, SMUMeasurement | None]]
Get raw per-device measurements collected during the last parallel run.
- Returns:
- Iterator of
(device, measurement)pairs in followers-then-leader order. Each measurement entry isNoneuntil data is fetched.
- Return type:
Iterator[tuple[Device, SMUMeasurement | None]]
Example
>>> for device, measurement in parallel_measurement.all_measurement_data: ... if measurement is None: ... print(f"{device.product}: no data yet") ... else: ... print(f"{device.product}: {len(measurement.voltage_values)} samples")
- property test_parameters: TestParameters
Get the current test parameters for the measurement.
Returns the configuration parameters that define how the measurement should be performed, including settings like powerline frequency and other measurement-specific parameters.
- Returns:
The current test parameters configuration
- Return type:
Examples
>>> measurement = Measurement(device) >>> params = measurement.test_parameters >>> print(params.powerline_frequency) PowerlineFrequency.FREQ_60_HZ
- property result: float | SMUResult | LCRMeasurementResult | tuple[SMUResult, Ellipsis] | tuple[LCRMeasurementResult, Ellipsis] | tuple[tuple[nibcq.switch.SMUCellData, SMUResult], Ellipsis] | tuple[tuple[nibcq.switch.SMUCellData, tuple[SMUResult, Ellipsis]], Ellipsis] | tuple[tuple[str, tuple[datetime.datetime, datetime.datetime, float]], Ellipsis] | Any
Get the result of the last measurement.
Returns the measurement result from the most recent measurement operation. The result type depends on the specific measurement implementation and whether switching was used:
- Single measurements:
float for OCV and DCIR
SMUResult for ACIR
tuple[SMUResult, …] for EIS
- Switching measurements:
tuple[tuple[SMUCellData, SMUResult], …] for ACIR with switching
tuple[tuple[SMUCellData, tuple[SMUResult, …]], …] for EIS with switching
tuple[tuple[str, tuple[datetime, datetime, float]], …] for OCV with switching
- Returns:
float | SMUResult | tuple[SMUResult, …] | tuple[tuple[SMUCellData, SMUResult], …] | tuple[tuple[SMUCellData, tuple[SMUResult, …]], …] | tuple[tuple[str, tuple[datetime, datetime, float]], …] | Any: The measurement result(s). For switching measurements, returns a tuple of tuples where each inner tuple contains the cell data and its corresponding results.
- Raises:
RuntimeError – If no measurement has been performed yet or if the result is not available
- Return type:
Union[float, SMUResult, LCRMeasurementResult, tuple[SMUResult, Ellipsis], tuple[LCRMeasurementResult, Ellipsis], tuple[tuple[nibcq.switch.SMUCellData, SMUResult], Ellipsis], tuple[tuple[nibcq.switch.SMUCellData, tuple[SMUResult, Ellipsis]], Ellipsis], tuple[tuple[str, tuple[datetime.datetime, datetime.datetime, float]], Ellipsis], Any]
Examples
>>> measurement.run(test_parameters) >>> result = measurement.result >>> print(f"Measurement result: {result}") >>> >>> # For switching measurements >>> switching_results = measurement.run_with_switching(compensation) >>> for cell_data, cell_results in measurement.result: ... print(f"Cell {cell_data.cell_serial_number}: {len(cell_results)} results")
- property compensation: Compensation | None
Get the compensation object for error correction.
- Returns:
The compensation data, or None if no compensation is applied.
- Return type:
Compensation | None
- run(compensation: Compensation | None = None, **kwargs)
Run the measurement process (Template Method).
Defines the invariant measurement workflow:
Optionally set compensation from argument.
Store any extra keyword arguments in
_run_kwargsso hook methods can access them.Validate preconditions (temperature, etc.) — before locking.
Lock all device sessions.
Execute the workflow (configure → measure → calculate → compensate).
Release locks.
Clear
_run_kwargs.Return result.
Subclasses customize behavior by overriding the abstract/hook methods:
_configure,_measure,_calculate,_apply_compensation,_validate_preconditions,_lock_sessions,_run_workflow.- Parameters:
compensation (Compensation | None) – Optional compensation data for error correction. If provided, sets
self._compensationbefore running. If None, uses the previously setself._compensation(which may also be None, meaning no compensation is applied).kwargs (Any) – Additional keyword arguments (
**kwargs) forwarded to hook methods viaself._run_kwargs. Subclasses may read specific keys from this dict inside their_run_workflowor other hooks.
- Returns:
The measurement result (type depends on the specific subclass).
- Return type:
Any
- property acceptable_temperature_delta: float
Get the acceptable temperature delta for compensation validation.
Returns the maximum allowed temperature difference from the device’s temperature capability. This is a pass-through property that delegates to the underlying TemperatureCapability.
- Returns:
The acceptable temperature delta in degrees, or NaN if no temperature capability
- Return type:
Examples
>>> measurement = EIS(device) >>> measurement.acceptable_temperature_delta = 2.5 >>> delta = measurement.acceptable_temperature_delta
- property temperature: float
Get the latest temperature reading from the device.
- Returns:
The most recent temperature measurement, or NaN if no temperature capability
- Return type:
- property temperature_range: CenteredRange
Get the latest temperature reading from the device, coupled with the user-set delta.
- Returns:
A CenteredRange representing the most recent temperature measurement (NaN if not available), along with the acceptable temperature delta (NaN if not set).
- Return type:
- measure_temperature() CenteredRange
Get a new temperature reading from the device.
- Returns:
Current temperature reading, or NaN if no temperature capability
- Return type:
- validate_temperature(target_temperature: CenteredRange) bool
Validate the current temperature against the compensation file’s target.
Delegates to the device’s temperature capability for validation. The capability handles all validation logic including checking if thermocouple is configured, using overridden delta values if set, and printing appropriate warnings.
- Parameters:
target_temperature (CenteredRange) – The target temperature parameters for validation
- Returns:
- True if thermocouple is configured and temperature is within range.
False if thermocouple is not configured (capability missing or not set up), or if target temperature/delta is NaN.
- Return type:
- Raises:
TemperatureError – If the current temperature exceeds the target ± delta range (only raised when capability is configured)
Examples
>>> measurement = EIS(device) >>> measurement.measure_temperature() >>> target = compensation.temperature_parameter >>> is_valid = measurement.validate_temperature(target)