ampworks#
Summary
ampworks is a collection of tools designed to visualize and process
experimental battery data. It provides routines for degradation mode analysis,
parameter extraction from common protocols (e.g., GITT, ICI, etc.), and more.
These routines provide key properties for life and physics-based models (e.g.,
SPM and P2D). Graphical user interfaces (GUIs) are available for some of the
analyses. See a list of the GUI-based applications by running ampworks -h
in your terminal after installation.
Note: ampworks is in early development. The API may change as it matures.
Accessing the Documentation
Documentation is accessible via Python’s help() function which prints
docstrings from a package, module, function, class, etc. You can also access
the documentation by visiting the website, hosted on Read the Docs. The website
includes search functionality and more detailed examples.
Submodules#
Classes#
Readable label for cycles. |
|
General dataset. |
|
Header alias definitions. |
|
A set of step, cycle, and section labels. |
|
Readable label for sections. |
|
Readable label for a single step. |
Functions#
|
Apply labels to a dataset. |
|
Read a csv file. |
|
Read an Excel file. |
|
Read a tab-delimited file. |
|
Map source columns to |
Package Contents#
- class ampworks.CycleLabel(label, *, steps=None, cycles=None)[source]#
Readable label for cycles.
- Parameters:
label (str) – The label to apply for the cycle.
steps (Sequence[int] or None, optional) – The step numbers that define the cycle. Defaults to None. Must be provided if
cyclesis not.cycles (Sequence[int] or None, optional) – The cycle numbers that define the cycle. Defaults to None. Must be provided if
stepsis not.
- Raises:
TypeError – If the
labelis not a string or ifstepsorcyclesis not a sequence of integers.ValueError – If both
stepsandcyclesareNone, or if both are notNone.
Notes
Either
stepsorcyclesmust be provided, but not both. Ifstepsis provided, the label will be applied to all cycles that contain those steps. Otherwise, ifcyclesis provided, the label will be applied to those cycles.Examples
The following demonstrates how to create cycle labels for a dataset. The inputs must be a string label and either a sequence of step numbers or a sequence of cycle numbers. Each label can only be defined using either steps or cycles, not both. However, when applying the labels, there are no restrictions on mixing cycle labels defined using both methods. Also, you can use a
rangeobject to define your sequence if more convenient, so there is no need to explicitly list all step or cycle numbers.>>> from ampworks import CycleLabel >>> cycle1 = CycleLabel('HPPC', steps=range(1, 9)) >>> cycle2 = CycleLabel('Aging Cycle', cycles=[1, 2, 3, 4, 5])
- class ampworks.Dataset(data=None, index=None, columns=None, dtype=None, copy=None)[source]#
General dataset.
- downsample(*, n=None, frac=None, resolution=None, inplace=False, ignore_index=False, keep_last=False)[source]#
Downsample the dataset by eliminating rows given:
number of rows
fraction of rows
resolution of a specified column
- Parameters:
n (int, optional) – Number of evenly spaced rows to keep, by default None.
frac (float, optional) – Fraction (in (0, 1]) of evenly spaced rows to keep, by default None.
resolution (tuple[str, float], optional) – Column (str) and resolution (float) to use for downsampling based on the absolute difference between adjacent values. By default None.
inplace (bool, optional) – Modify in place if True. If False (default), return a new Dataset.
ignore_index (bool, optional) – If True, reset the indices. Default is False.
keep_last (bool, optional) – If True, always keep the last row. Default is False.
- Returns:
data (Dataset or None) – The downsampled Dataset if ‘inplace’ is False. Otherwise, None.
- Raises:
ValueError – If more than one of n, frac, resolution is specified, or if they are all None. Also, if n is not positive or frac is not in (0, 1].
Examples
The following demonstrates three ways to downsample a dataset. Note that only the
resolutionoption requires a column to operate on.import ampworks as amp data = amp.datasets.load_datasets('dqdv/cell1_rough') # keep 100 evenly spaced rows sample1 = data.downsample(n=100) # keep 50% of the data, dropping evenly spaced rows sample2 = data.downsample(frac=0.5) # ensure adjacent voltage readings are at least 1 mV apart sample3 = data.downsample(resolution=('Volts', 1e-3))
- enforce_monotonic(column, increasing=True, strict=False, inplace=False, ignore_index=False)[source]#
Enforce monotonicity in a column by dropping rows that break the trend.
- Parameters:
column (str) – Column name to enforce monotonicity on.
increasing (bool, optional) – If True (default), enforce increasing monotonicity. Otherwise, apply decreasing monotonicity.
strict (bool, optional) – If True, enforce strict monotonicity (no equal adjacent values). The default is False, which allows equal adjacent values.
inplace (bool, optional) – Modify in place if True. If False (default), return a new Dataset.
ignore_index (bool, optional) – If True, reset the indices. Default is False.
- Returns:
data (Dataset or None) – The modified Dataset if ‘inplace’ is False. Otherwise, None.
- interactive_bokeh(x, y, *, tips=None, figsize=(800, 450), kind='line', save=None)[source]#
Create an interactive bokeh figure with hover tips. Optionally save as a standalone HTML file, viewable without installing Python/ampworks.
- Parameters:
x (str) – Column name for the variable to plot on the x-axis.
y (str) – Column name for the variable to plot on the y-axis.
tips (list[str] or None, optional) – List of column names to display as hover tips, by default None.
figsize (tuple[int | None, int | None], optional) – Figure size (width, height) in pixels, by default (800, 450). Set either or both dimensions to None to allow them to stretch.
kind ({'line', 'scatter', 'both'}, optional) – Type of plot to create. ‘line’ (default) for a line plot, ‘scatter’ for a scatter plot, or ‘both’ to show both a line and markers.
save (str, optional) – File path to save the plot as an HTML file, by default None.
See also
interactive_plotlyInteractive plots using plotly. Typically has lower performance for large (>250k) datasets, but is compatible with
dashapps.
Notes
The responsive height size option is limited in notebook environments since output cells do not have adjustable heights. In these cases, the height is set to a default minimum value.
Examples
The following creates an interactive plot of an HPPC discharge dataset. Note that the x, y, and tips values must be existing columns; however, you can compute or add new columns before plotting, if needed, as shown by adding an ‘Hours’ column in the second figure below. Also, hovertips must be passed as a list, even if only one column is requested.
import ampworks as amp data = amp.datasets.load_datasets('hppc/hppc_discharge') data.interactive_bokeh('Seconds', 'Volts', tips=['Step']) # Add new column to plot time in hours instead of seconds data['Hours'] = data['Seconds'] / 3600 data.interactive_bokeh('Hours', 'Volts', tips=['Step', 'Amps'])
- interactive_plotly(x, y, *, tips=None, figsize=(800, 450), kind='line', save=None)[source]#
Create an interactive plotly figure with hover tips. Optionally save as a standalone HTML file, viewable without installing Python/ampworks.
- Parameters:
x (str) – Column name for the variable to plot on the x-axis.
y (str) – Column name for the variable to plot on the y-axis.
tips (list[str] or None, optional) – List of column names to display as hover tips, by default None.
figsize (tuple[int | None, int | None], optional) – Figure size (width, height) in pixels, by default (800, 450). Set either or both dimensions to None to allow them to stretch.
kind ({'line', 'scatter', 'both'}, optional) – Kind of plot to draw. ‘line’ (default) for a line plot, ‘scatter’ for a scatter plot, or ‘both’ to show both a line and markers.
save (str, optional) – File path to save the plot as an HTML file, by default None.
See also
interactive_bokehInteractive plots using bokeh. Typically has higher performance for large (>250k) datasets and better support for notebook exports.
Notes
The responsive height size option is limited in notebook environments since output cells do not have adjustable heights. In these cases, the height is set to a default minimum value.
Examples
The following creates an interactive plot of an HPPC discharge dataset. Note that the x, y, and tips values must be existing columns; however, you can compute or add new columns before plotting, if needed, as shown by adding an ‘Hours’ column in the second figure below. Also, hovertips must be passed as a list, even if only one column is requested.
import ampworks as amp data = amp.datasets.load_datasets('hppc/hppc_discharge') data.interactive_plotly('Seconds', 'Volts', tips=['Step']) # Add new column to plot time in hours instead of seconds data['Hours'] = data['Seconds'] / 3600 data.interactive_plotly('Hours', 'Volts', tips=['Step', 'Amps'])
- zero_below(column, threshold, inplace=False)[source]#
Set values in ‘column’ below ‘threshold’ to zero.
- Parameters:
column (str) – Column name to apply thresholding.
threshold (float) – Values whose absolute value is below this threshold are set to zero. Note that values equal to the threshold are not zeroed.
inplace (bool, optional) – Modify in place if True. If False (default), return a new Dataset.
- Returns:
data (Dataset or None) – The modified Dataset if ‘inplace’ is False. Otherwise, None.
Examples
Small non-zero values that can be attributed to noise can interfere with some analysis methods. For example, automatic pulse detection identifies pulses based on transitions from zero to non-zero current. This example filters out currents below 1% of the mean non-rest current, though the thresholds should be tailored to your specific use case and data.
import ampworks as amp # zero out currents below a threshold from non-rest data data = amp.datasets.load_datasets('hppc/hppc_discharge') threshold = data.loc[data['State'] != 'R', 'Amps'].mean()*1e-2 data_zeroed = data.zero_below(column='Amps', threshold=threshold)
- zero_time(inplace=False)[source]#
Shifts the
Secondscolumn by subtracting the first row’s value to set a new zero reference.- Parameters:
inplace (bool, optional) – Modify in place if True. If False (default), return a new Dataset.
- Returns:
data (Dataset | None) – The modified Dataset if ‘inplace’ is False. Otherwise, None.
Notes
This method does not sort by time, nor does it use the minimum time when subtracting. It simply shifts the time values so that the first row has a time of zero, regardless of the actual order of time values. Consider sorting by time first, if needed, using
data.sort_values('Seconds').
- class ampworks.HeaderAliases(*, Seconds=None, Amps=None, Volts=None, Cycle=None, Step=None, State=None, Ah=None, Wh=None, DateTime=None)[source]#
Header alias definitions.
A container that allows users to specify custom header aliases for their data. These are used to automatically find and standardize columns when loading data.
ampworksuses default aliases for any headers that are not provided here.- Parameters:
Seconds (str or list[str] or None, optional) – Aliases for the standardized Seconds column.
Amps (str or list[str] or None, optional) – Aliases for the standardized Amps column.
Volts (str or list[str] or None, optional) – Aliases for the standardized Volts column.
Cycle (str or list[str] or None, optional) – Aliases for the standardized Cycle column.
Step (str or list[str] or None, optional) – Aliases for the standardized Step column.
State (str or list[str] or None, optional) – Aliases for the standardized State column.
Ah (str or list[str] or None, optional) – Aliases for the standardized Ah column.
Wh (str or list[str] or None, optional) – Aliases for the standardized Wh column.
DateTime (str or list[str] or None, optional) – Aliases for the standardized DateTime column.
Examples
The following example shows how to use
HeaderAliasesto specify custom aliases. Any inputs that are skipped will use a list of defaults. Note that you can provide a single alias or many for each standard header. Be aware that all parameters must be provided as keywords to avoid improper ordering.>>> import ampworks as amp >>> aliases = amp.HeaderAliases( ... Seconds='elapsed_s', ... Amps=['current_amps', 'current_a'], ... )
- class ampworks.LabelSet(*, step_labels=None, cycle_labels=None, section_labels=None)[source]#
A set of step, cycle, and section labels.
- Parameters:
step_labels (Sequence[StepLabel] or None, optional) – The step labels for a given dataset. Defaults to None.
cycle_labels (Sequence[CycleLabel] or None, optional) – The cycle labels for a given dataset. Defaults to None.
section_labels (Sequence[SectionLabel] or None, optional) – The section labels for a given dataset. Defaults to None.
- Raises:
TypeError – If any of the label inputs are not sequences of the appropriate label type, e.g. if
step_labelsis not a sequence ofStepLabel.
- class ampworks.SectionLabel(label, *, steps=None, cycles=None)[source]#
Readable label for sections.
- Parameters:
label (str) – The label to apply for the section.
steps (Sequence[int] or None, optional) – The step numbers that define the section. Defaults to None. Must be provided if
cyclesis not.cycles (Sequence[int] or None, optional) – The cycle numbers that define the section. Defaults to None. Must be provided if
stepsis not.
- Raises:
TypeError – If the
labelis not a string or ifstepsorcyclesis not a sequence of integers.ValueError – If both
stepsandcyclesareNone, or if both are notNone.
Notes
Either
stepsorcyclesmust be provided, but not both. Ifstepsis provided, the label will be applied to all cycles that contain those steps. Otherwise, ifcyclesis provided, the label will be applied to those cycles.Examples
The following demonstrates how to create section labels for a dataset. A section label is intended to be one level of abstraction higher than a cycle label.
The inputs must be a string label and either a sequence of step numbers or a sequence of cycle numbers. Each label can only be defined using either steps or cycles, not both. However, when applying the labels, there are no restrictions on mixing section labels defined using both methods. Also, you can use a
rangeobject to define your sequence if more convenient, so there is no need to list all step or cycle numbers.>>> from ampworks import SectionLabel >>> section1 = SectionLabel('RPT1', cycles=[1, 2, 3]) >>> section2 = SectionLabel('RPT2', cycles=range(100, 104))
- class ampworks.StepLabel(label, step)[source]#
Readable label for a single step.
- Parameters:
label (str) – The label to apply for the step, defined by the ‘step’ argument.
step (int) – The step number to which the label will be applied.
- Raises:
TypeError – If
labelis not a string or ifstepis not an integer.
Examples
The following demonstrates how to create step labels for a dataset. The inputs must be a string label and an integer step number. The label can be as simple or descriptive as desired.
>>> from ampworks import StepLabel >>> step1 = StepLabel('Initial Rest', 1) >>> step2 = StepLabel('1C CC Charge until 4.2V', 2) >>> step3 = StepLabel('CV Charge at 4.2V', 3) >>> step4 = StepLabel('Final Rest', 4)
- ampworks.apply_labels(data, labels)[source]#
Apply labels to a dataset.
- Parameters:
- Returns:
labeled (Dataset) – A new dataset with the applied labels.
- Raises:
TypeError – If
datais not a Dataset or iflabelsis not a LabelSet.ValueError – If
datadoes not contain the required ‘Cycle’ and ‘Step’ columns.
See also
Dataset.interactive_plotlyInteractively inspect the labeled dataset with plotly hover tips.
Dataset.interactive_bokehSame using bokeh; better suited for large datasets.
Notes
Any cycles or steps that are not labeled will have a label of
'None'in the resultingCycleLabelandStepLabelcolumns. Also, if a step is given in more than one cycle, the last cycle label will be applied. Similarly, if a step is given more than one step label, only the last step label will be applied to that step.Examples
The following demonstrates how to apply labels to an HPPC dataset from the
ampworks.datasetsmodule. First, we create the labels and them apply them to the dataset. The final line of code plots the resulting dataset with some hover hints so the applied labels can be viewed and checked for accuracy.import ampworks as amp # Load in an example dataset data = amp.datasets.load_datasets('hppc/hppc_discharge') # Create the labels labels = amp.LabelSet( step_labels=[ amp.StepLabel('Initial Rest', 1), amp.StepLabel('C/3 Discharge', 2), amp.StepLabel('Equilibrium Rest', 3), amp.StepLabel('1C Discharge Pulse', 4), amp.StepLabel('40s Rest', 5), amp.StepLabel('0.75C Charge Pulse', 6), amp.StepLabel('40s Rest', 7), amp.StepLabel('Final Rest', 8), ], cycle_labels=[ amp.CycleLabel('HPPC', steps=range(1, 9)), ], ) # Apply the labels labeled = amp.apply_labels(all_data, labels) # Add an hours column and plot with the labels as hover tips labeled['Hours'] = labeled['Seconds'] / 3600 labeled.interactive_plotly( x='Hours', y='Volts', tips=['StepLabel', 'CycleLabel'], )
- ampworks.read_csv(filepath, aliases=None, extra_columns=None)[source]#
Read a csv file.
Custom reading function for comma-separated values (CSV) files. Scans the file to identify expected headers (see Notes for specifics). This routine is not specific to any particular cycler. Instead, it uses default internal or user-defined aliases to find and standardize the headers, columns, and data types.
- Parameters:
filepath (PathLike) – Path to the file, including extension.
aliases (HeaderAliases or None, optional) – Column alias mapping for the header standardization. If None (default), a set of internal default aliases is used.
extra_columns (dict[str, type or None] or None, optional) – Additional columns to include in the standardized dataset. Include both the exact source column names and their corresponding data types in a dictionary. Use value None to keep pandas-inferred dtype. The
typeis also compatible with pandas dtypes, e.g.,'string','Int64', etc.
- Returns:
data (Dataset) – Standardized battery dataset.
Warning
- UserWarning
If
extra_columnsare not found in the source data or conflict with any of the standardized headers. Also, if no valid headers are found and an empty dataset is returned.
See also
HeaderAliasesCustom column mapping for standardization.
Notes
By default, only aliases of Seconds, Amps, Volts, Cycle, Step, State, Ah, Wh, and DateTime are included. If you’d like to ensure that additional data columns are included, use the
extra_columnsparameter.Examples
The following example shows how to read in data from a
.csvfile using a few of the available options.import ampworks as amp # read in the file using all default options data = amp.read_csv('data.csv') # specify custom aliases for a couple column headers aliases = amp.HeaderAliases(Seconds='Time_s', Amps='Current_A') data = amp.read_csv('data.csv', aliases=aliases) # include extra columns for temperature and notes extra_cols = {'Temperature': float, 'Notes': None} data = amp.read_csv('data.csv', extra_columns=extra_cols)
- ampworks.read_excel(filepath, sheet_name=None, stack_sheets=False, aliases=None, extra_columns=None)[source]#
Read an Excel file.
Custom reading function for Excel files. Scans all (or some) of the sheets to identify expected headers (see Notes for specifics). This routine is not specific to any particular cycler. Instead, it uses internal or user-defined aliases to find and standardize the headers, columns, and data types.
- Parameters:
filepath (PathLike) – Path to the file, including extension.
sheet_name (str or int or Sequence[str or int] or None, optional) – Name or index of the sheet(s) to read. For integers, use natural indices from 1 to the number of sheets. None (default) will scan for the first sheet with valid headers. Use
'all'to read all sheets.stack_sheets (bool, optional) – If True, concatenate all parsed sheets into one dataset.
aliases (HeaderAliases or None, optional) – Column alias mapping for the header standardization. If None (default), a set of internal default aliases is used.
extra_columns (dict[str, type or None] or None, optional) – Extra source columns to preserve using exact source names as keys. The values define cast type. Use None to keep inferred dtype. Both Python types and pandas dtypes are accepted, e.g.,
'string','Int64', etc.
- Returns:
data (Dataset or dict[str or int, Dataset]) – Standardized dataset output. A dictionary is returned if multiple sheets are read and
stack_sheetsis False.- Raises:
ValueError – If the parameter (or any of the elements in)
sheet_nameare invalid names or indices.
Warning
- UserWarning
If
extra_columnsare not found in the source data or conflict with any of the standardized headers. Also, if no valid headers are found and an empty dataset is returned.
See also
HeaderAliasesCustom column mapping for standardization.
Notes
By default, only aliases of Seconds, Amps, Volts, Cycle, Step, State, Ah, Wh, and DateTime are included. If you’d like to ensure that additional data columns are included, use the
extra_columnsparameter.Examples
The following example shows how to read in data from an Excel file using a few of the available options. Note that the examples demonstrate different extensions that are both types of Excel files.
import ampworks as amp # read in the file using all default options data = amp.read_excel('data.xls') # specify custom aliases for a couple column headers aliases = amp.HeaderAliases(Seconds='Time_s', Amps='Current_A') data = amp.read_excel('data.xls', aliases=aliases) # include extra columns for temperature and notes extra_cols = {'Temperature': float, 'Notes': None} data = amp.read_excel('data.xls', extra_columns=extra_cols) # specify the second sheet and a sheet named 'last' data = amp.read_excel('data.xlsx', sheet_name=[2, 'last']) # read in all sheets and concatenate the results data = amp.read_excel('data.xlsx', sheet_name='all', stack_sheets=True)
- ampworks.read_table(filepath, aliases=None, extra_columns=None)[source]#
Read a tab-delimited file.
Custom reading function for tab-delimited files. Scans the file to identify expected headers (see Notes for specifics). This routine is not specific to any particular cycler. Instead, it uses internal or user-defined aliases to find and standardize the headers, columns, and data types.
- Parameters:
filepath (PathLike) – Path to the file, including extension.
aliases (HeaderAliases or None, optional) – Column alias mapping for the header standardization. If None (default), a set of internal default aliases is used.
extra_columns (dict[str, type or None] or None, optional) – Extra source columns to preserve using exact source names as keys. The values define cast type. Use None to keep inferred dtype. Both Python types and pandas dtypes are accepted, e.g.,
'string','Int64', etc.
- Returns:
data (Dataset) – Standardized battery dataset.
Warning
- UserWarning
If
extra_columnsare not found in the source data or conflict with any of the standardized headers. Also, if no valid headers are found and an empty dataset is returned.
See also
HeaderAliasesCustom column mapping for standardization.
Notes
By default, only aliases of Seconds, Amps, Volts, Cycle, Step, State, Ah, Wh, and DateTime are included. If you’d like to ensure that additional data columns are included, use the
extra_columnsparameter.Examples
The following example shows how to read in data from a
.txtfile using a few of the available options.import ampworks as amp # read in the file using all default options data = amp.read_table('data.txt') # specify custom aliases for a couple column headers aliases = amp.HeaderAliases(Seconds='Time_s', Amps='Current_A') data = amp.read_table('data.txt', aliases=aliases) # include extra columns for temperature and notes extra_cols = {'Temperature': float, 'Notes': None} data = amp.read_table('data.txt', extra_columns=extra_cols)
- ampworks.standardize_headers(data, aliases=None, extra_columns=None)[source]#
Map source columns to
ampworksstandards.- Parameters:
data (pandas.DataFrame) – Source data frame with raw cycler headers.
aliases (HeaderAliases or None, optional) – Alias mapping used to identify standardized columns. If None, defaults are used.
extra_columns (dict[str, type or None] or None, optional) – Extra source columns to keep in output using exact source names as keys. Values define cast type. Use None to keep inferred dtype.
- Returns:
data (Dataset) – Standardized dataset.
Warning
- UserWarning
Raised when standardized aliases are missing, requested extra columns are not found, or requested extra columns conflict with standardized output columns.