ampworks.hppc#

Tools to analyze Hybrid Pulse Power Characterization (HPPC) data. Includes functions to detect pulses within the protocol and to extract the electrical impedance from those pulses.

Functions#

extract_impedance(data[, tmin, tmax, sample_times, ...])

Extract impedance from HPPC data.

Package Contents#

ampworks.hppc.extract_impedance(data, tmin=0.0, tmax=20.0, sample_times=None, steps=None, area=None, plot=False, **fig_kw)[source]#

Extract impedance from HPPC data.

HPPC, or hybrid pulse power characterization, is a common protocol used to measure the power capability and internal resistance. The protocol consists of a series of charge and/or discharge pulses performed at various states of charge. This function extracts the impedance during these pulses. The pulses can either be autodetected based on state transitions from rest and non-rest periods, or explicitly specified using step numbers. By default, only the instantaneous and end-of-pulse impedance values are reported, but additional sample times can be specified in the input. The “instantaneous” impedance is defined as the impedance calculated using the first sample after the pulse start. The “end” impedance is calculated using the last sample before the pulse end.

Area specific impedance (ASI) is also calculated if the electrode or cell area is provided. Otherwise, the output will only provide the absolute impedance in Ohms. ASI, when provided, is reported in Ohms-cm2. Make sure the area is in cm2 to ensure correct units.

There are many ways to write an HPPC protocol. If you’re looking for a place to start, consider reading through the recommendations provided by Idaho National Labs [1]. Or, consider using the HPPC protocol provided below, which was used for testing the algorithm. Note that the algorithm assumes that a cell starts at 100% SOC.

  1. Rest for 60 minutes

  2. Discharge at C/3 for 18 minutes (~10% SOC)

  3. Rest for 60 minutes

  4. Discharge at 1C for 30 seconds

  5. Rest for 40 seconds

  6. Charge at 0.75C for 10 seconds

  7. Rest for 40 seconds

  8. Repeat steps 2-7 until 10% SOC is reached

  9. Discharge at C/3 until lower voltage limit

  10. Rest for 60 minutes

This protocol extracts impedance at nine SOC points, roughly between 10% and 90%. This is to make sure that the protocol does not exceed upper or lower voltage limits during the pulse as the cell nears 100% or 0% SOC. Note that the pulse currents and durations are different in the charge and discharge directions. This is not a requirement, but was convenient for testing the algorithm. In the example dataset, samples were logged every 0.1 seconds for steps 4-7 above, and every 10 seconds for all other steps.

Parameters:
  • data (Dataset) – The sliced HPPC data to process. Must have, at a minimum, the columns for {'Seconds', 'Volts', 'Amps'}. See notes for more information.

  • tmin (float, optional) – Minimum pulse duration in seconds, by default 0.

  • tmax (float, optional) – Maximum pulse duration in seconds, by default 20.

  • sample_times (list[float] or None, optional) – Relative times to sample each pulse’s impedance, in seconds. If None (default), only “instantaneous” and end of pulse impedance are reported. NaN is used for sample times that cannot be interpolated.

  • steps (list[int] or None, optional) – Explicit list of step numbers associated with HPPC pulses. If None, pulses are autodetected based on state transitions. Requires a Step column in data. Defaults to None.

  • area (float, optional) – Electrode or cell area in cm2. Used to calculate area specific impedance (ASI) in Ohms-cm2. If None (default), ASI values are not reported.

  • plot (bool, optional) – Whether to plot the current and voltage profiles with detected pulses highlighted, by default False.

  • **fig_kw (dict, optional) – Additional keyword arguments to use when plotting. A full list of names, types, descriptions, and defaults is given below.

  • figsize ((int, int) or None, optional) – Figure size (width, height) in pixels. Set either dimension to None for responsiveness. In Jupyter, only width can resize; height is fixed. The default is (800, 500).

  • save (str or None, optional) – Path to save the plot as HTML. If not in a Jupyter notebook and save is None, a temporary file is still created and is opened in the browser.

Returns:

impedance (pd.DataFrame) – Impedance table with ‘PulseNum’, ‘State’, ‘Hours_0’, ‘SOC_0’, ‘AmpsAvg’, and ‘StepTime_i’, ‘Volts_i’, ‘Ohms_i’, and ‘ASI_i’ columns. Index i marks: 0=pre-pulse, 1=instantaneous, 2..k=sample times, N=end. Note that ASI is only reported if ‘area’ is provided.

Notes

Rests within the dataset are expected to have a current exactly equal to zero. The autodetection routine for pulses relies on this to identify pulse start and end times. If you need to zero out currents below a threshold, you can use data.zero_below('Amps', threshold) before calling this function. Furthermore, even when using explicit ‘steps’, the algorithm checks for rest periods before and after each pulse. If these are not present, the pulse is ignored.

This algorithm expects charge/discharge currents to be positive/negative, respectively. If your sign convention is the opposite, ‘SOC_0’ values in the output will be incorrect. Furthermore, the algorithm assumes the protocol starts at either 0% or 100% SOC and ends at the opposite extreme. If this is not the case, the ‘SOC_0’ values in the output will be incorrect.

References

Examples

>>> import seaborn as sns
>>> import ampworks as amp
>>> data = amp.datasets.load_datasets('hppc/hppc_discharge')
>>> impedance = amp.hppc.extract_impedance(data, tmax=31, sample_times=[5])
>>> ax = sns.scatterplot(data=impedance, x='SOC_0', y='Ohms_2', hue='State')
>>> ax.set_xlabel('SOC [-]')
>>> ax.set_ylabel('R5 [Ohms]')
>>> print(impedance)