nibcq.ACIR ========== .. py:class:: nibcq.ACIR(device: nibcq._device.Device, test_parameters: ACIRTestParameters, test_frequency: float = 1000) Bases: :py:obj:`nibcq.measurement.Measurement` Alternating Current Internal Resistance (ACIR) measurement handler class. This class implements single-frequency AC impedance spectroscopy measurements using a Source Measure Unit (SMU). ACIR measurements characterize the complex impedance of electrochemical systems, batteries, and other devices by applying a sinusoidal current excitation and measuring the resulting voltage response. The class handles the complete measurement workflow including signal generation, data acquisition, DFT analysis for impedance calculation, and error compensation. It provides a foundation for more complex measurements like EIS (Electrochemical Impedance Spectroscopy) which extends ACIR for frequency sweeps. ACIR measurements are fundamental in battery testing, electrochemical analysis, and material characterization where understanding the frequency-dependent impedance behavior is crucial for system performance evaluation. .. rubric:: Example >>> # Configure measurement parameters >>> params = ACIRTestParameters( ... current_amplitude=0.1, ... number_of_periods=20, ... compensation_method=CompensationMethod.SHORT ... ) >>> >>> device = Device.connect("PXIe-4139") >>> acir = ACIR(device, test_frequency=1000.0, test_parameters=params) >>> >>> # Run measurement at 1000 Hz >>> compensation = Compensation() >>> result = acir.run(compensation=compensation) >>> print(f"Impedance: {abs(result.impedance):.2f} Ohms") .. py:attribute:: DEVICE_FAMILY :type: Final[nibcq.enums.DeviceFamily] Device family for ACIR and similar measurement types. :type: DeviceFamily .. py:attribute:: FREQUENCY_LIMIT :type: Final[float] :value: 10000.0 Frequency limit for ACIR and similar measurement types. :type: float .. py:attribute:: CURRENT_LIMIT :type: Final[float] :value: 2.0 Current limit for ACIR and similar measurement types. :type: float .. py:property:: current_frequency :type: float Get the current frequency of the ACIR Measurement. :returns: The current configured frequency in Hz :rtype: float :raises ValueError: If frequency has not been set .. py:property:: test_parameters :type: ACIRTestParameters Get the test parameters for ACIR measurement. :returns: The current test parameters configuration :rtype: ACIRTestParameters :raises ValueError: If test parameters have not been set .. py:property:: result :type: Union[nibcq.measurement.SMUResult, list[tuple[nibcq.switch.SMUCellData, nibcq.measurement.SMUResult]]] Get the result of the last ACIR measurement. Returns the measurement result from the most recent measurement operation. The result type depends on whether switching was used or not. :returns: The measurement result(s). For switching measurements, returns a list of tuples where each tuple contains the cell data and its corresponding results. :rtype: SMUResult | list[tuple[SMUCellData, SMUResult]] :raises RuntimeError: If no measurement has been performed yet or if the result is not available .. py:method:: generate_compensation_file_path() -> str Generate compensation file path using current compensation method setting. :returns: The generated file path for compensation data, or None if no compensation is needed :rtype: str :raises NotImplementedError: If compensation_method is not supported by nibcq Python API :raises ValueError: If test parameters are not set .. py:property:: measurement_data :type: nibcq.measurement.SMUMeasurement Get the processed measurement data used for impedance calculations. Only allows measurement to be read, not access it directly. For frequencies > 60 Hz, sanitizes data by removing edge effects. Applies DC offset removal to ensure measurements start and end near zero. :returns: Sanitized measurement data containing tone frequency, voltage values, and current values :rtype: SMUMeasurement :raises ValueError: If no measurement data is available or measurement is incomplete .. py:property:: raw_data :type: nibcq.measurement.SMUMeasurement Get the raw measurement data read from the device. Only allows measurement to be read, not access it directly. Returns unprocessed data as captured from the device. :returns: Raw measurement data containing tone frequency, voltage values, and current values :rtype: SMUMeasurement :raises ValueError: If no measurement data is available or measurement is incomplete .. py:method:: validate_current_amplitude(current_amplitude: float) -> bool :staticmethod: Validate that the current amplitude is within acceptable limits. .. py:method:: load_compensation_file(file_path: Optional[str] = None) -> nibcq.compensation.Compensation Load compensation file based on compensation method and device serial number. Creates and returns a compensation object with the appropriate compensation data. For NO_COMPENSATION, creates a default compensation object. For other methods, loads compensation data from file. :param file_path: Optional specific file path to read from. If None, generates path automatically :type file_path: Optional[str] :returns: The loaded compensation object :rtype: Compensation :raises FileNotFoundError: If compensation file is not found and compensation is required :raises ValueError: If compensation file is invalid and compensation is required :raises NotImplementedError: If compensation method is not supported by the nibcq Python API .. py:method:: run(compensation: nibcq.compensation.Compensation) -> nibcq.measurement.SMUResult Run the complete ACIR measurement process with the specified parameters. Validates temperature if the compensation specifies a target temperature, and the device supports temperature measurement. Then configures the device, performs the measurement, applies compensation if specified, and returns the final impedance results. :param compensation: The compensation object to use for impedance correction :type compensation: Compensation :returns: A complete measurement result containing compensated impedance data including frequency, impedance, resistance, reactance, magnitude, and phase :rtype: SMUResult :raises ValueError: If test frequency is out of range or parameters are invalid. :raises Also raised if temperature validation fails.: :raises FileNotFoundError: If compensation file is required but not found :raises RuntimeError: If device configuration or measurement fails :raises NotImplementedError: If unsupported compensation method is specified .. rubric:: Examples >>> params = ACIRTestParameters() >>> acir = ACIR(device, params) >>> compensation = acir.load_compensation_file() >>> results = acir.run(1000, compensation) .. py:method:: run_with_switching(compensation: nibcq.compensation.Compensation) -> list[tuple[nibcq.switch.SMUCellData, nibcq.measurement.SMUResult]] Run ACIR measurements across multiple DUTs using switch matrix configuration. This method performs AC impedance measurements on multiple devices under test (DUTs) by automatically switching between different channels. It leverages the device's switching capability to sequentially connect to each configured DUT, perform the ACIR measurement, and collect results for all channels. Returns partial, already processed measurements, even if an error occurs during switching or measurement. The switching process includes proper debounce timing to ensure stable connections before measurements, and automatic disconnection after each measurement to prevent interference. This enables efficient multi-DUT testing for battery characterization, production testing, or comparative analysis scenarios. :param compensation: The compensation object containing error correction data for impedance accuracy improvement across the measurement frequency. :type compensation: Compensation :returns: A list of tuples mapping each cell to its measurement result. Each SMUCellData represents a DUT connection point, and SMUResult contains the impedance, resistance, reactance, magnitude, and phase measurements for that specific DUT. :rtype: list[tuple[SMUCellData, SMUResult]] :raises RuntimeError: If switching capability is not enabled (call device.with_switching() first) or if no switch channels are configured in the switch matrix. :raises ValueError: If test_frequency is out of bounds, test_parameters contain invalid values that would cause measurement errors, or if compensation list length doesn't match the number of DUTs. Also raised if temperature validation fails for any cell. :raises Exception: If connection to any DUT fails during switching operations. .. note:: This method automatically handles switch timing with debounce delays to ensure measurement stability. The end guarantees proper disconnection even if exceptions occur during measurement, preventing DUT damage or interference. .. rubric:: Examples >>> params = ACIRTestParameters() >>> acir = ACIR(device, params) >>> compensation = acir.load_compensation_file() >>> results = acir.run_with_switching(1000, compensation) .. py:method:: write_compensation_file(compensation_file_path: Optional[str] = None, kit_file_path: Optional[str] = None, comment: Optional[str] = None) -> str Create a compensation file based on the current compensation data. :param compensation_file_path: Optional specific file path to write to. If None, generates path automatically. :type compensation_file_path: Optional[str] :param kit_file_path: Optional specific file path to the known impedance table. If None, no known impedance table is used. :type kit_file_path: Optional[str] :param comment: Optional comment to include in the compensation file. If None, no comment is included. :type comment: Optional[str] :returns: The path of the created compensation file. :rtype: string :raises ValueError: If test frequency is out of range, parameters are invalid or compensation method not supports compensation files. :raises FileNotFoundError: If compensation file is required but not found. :raises RuntimeError: If device configuration or measurement fails. :raises NotImplementedError: If unsupported compensation method is specified. .. py:property:: has_switch_capability :type: bool Check if the device has switch capability. :returns: True if switch capability is available, False otherwise .. py:method:: connect_channel(channel: SMUCellData) -> None Connect to a specific DUT channel using the device's switch capability. :param channel: SwitchChannel containing connection information :raises RuntimeError: If no switch capability is available .. py:method:: disconnect_all() -> None Disconnect all channels using the device's switch capability. :raises RuntimeError: If no switch capability is available .. py:method:: wait_for_debounce() -> None Wait for switch relays to settle using the device's switch capability. :raises RuntimeError: If no switch capability is available .. py:property:: switch_cells :type: List[str] | List[SMUCellData] Get the configured switch cells from the device. :returns: A list of DUT channel names or SMUCellData objects, which contain the DUT and switch channel information. .. py:property:: acceptable_temperature_delta :type: 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 :rtype: float .. rubric:: Examples >>> measurement = EIS(device) >>> measurement.acceptable_temperature_delta = 2.5 >>> delta = measurement.acceptable_temperature_delta .. py:property:: temperature :type: float Get the latest temperature reading from the device. :returns: The most recent temperature measurement, or NaN if no temperature capability .. py:property:: temperature_range :type: 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). .. py:method:: measure_temperature() -> CenteredRange Get a new temperature reading from the device. :returns: Current temperature reading, or NaN if no temperature capability .. py:method:: 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. :param target_temperature: 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. :rtype: bool :raises ValueError: If the current temperature exceeds the target ± delta range (only raised when capability is configured) .. rubric:: Examples >>> measurement = EIS(device) >>> measurement.measure_temperature() >>> target = compensation.temperature_parameter >>> is_valid = measurement.validate_temperature(target)