Skip to main content

eisfit

eisfit is a lightweight Python package for fitting electrochemical impedance spectroscopy (EIS) data and extracting equivalent-circuit parameters.

The package supports a two-arc equivalent circuit with either a CPE-type low-frequency tail or a semi-infinite Warburg tail:

Z = jωL + R0 + (R1 || CPE1) + (R2 || CPE2) + tail

It is designed for battery EIS analysis workflows where users need a simple Python API, a command-line tool, and reproducible fitted outputs.

Features

  • Load EIS data from CSV, XLS, and XLSX files
  • Fit complex impedance data with bounded multi-start least squares
  • Use either a flexible CPE tail or a Warburg diffusion tail
  • Export fitted parameters, simulated impedance, residuals, and Nyquist plots
  • Run from Python notebooks, scripts, or the command line
  • Use included demo files to test the workflow immediately after cloning

Installation

Install the released package from PyPI:

pip install eisfit

For local development from a cloned repository:

pip install -e ".[dev]"

Quick Start

Fit one EIS file directly:

from eisfit import fit_file

result = fit_file("my_eis.csv", tail="cpe", n_starts=40)

print(result.parameters)
print(result.rmse, result.nrmse)

Convergence and diagnostic records

Only optimizer starts that converge and return finite parameters, residuals, cost, fitted impedance and fit error can be selected. The lowest-cost accepted start is returned. If every start fails, fit() and fit_file() raise FitConvergenceError instead of returning an unconverged parameter set:

from dataclasses import asdict
from eisfit import FitConvergenceError, fit

try:
    result = fit(freq, Zexp)
except FitConvergenceError as error:
    attempts = [asdict(attempt) for attempt in error.attempts]
else:
    print(result.diagnostics)

Each attempted start records its index, optimizer success/status/message, evaluation count, cost, acceptance and rejection reason. A failed file fit does not write new fitted outputs. The CLI reports convergence failures as JSON and exits with status 1; a folder run continues with the remaining files and exits with status 1 if any file fails. Existing outputs from earlier runs are not removed, so consumers should use the current result's returned paths.

Convergence is a numerical termination condition. It does not establish a unique solution, adequate fit quality or a physical interpretation. identifiability_status is explicitly not_assessed.

Arc parameter ordering

Reported R1/Q1/n1 and R2/Q2/n2 are ordered by increasing characteristic time tau = (R * Q) ** (1 / n) for each parallel R-CPE branch. Arc 1 therefore has the higher characteristic frequency. Exact time ties use (R, Q, n) as a deterministic secondary ordering. The full fitted spectrum is unchanged.

This convention prevents an arbitrary exchange of the two branch labels. It does not assign SEI/charge-transfer processes, establish identifiability, or track the same physical arc across spectra, especially when the times overlap or cross.

result.parameters, p_opt, staged fit errors, parameter_bounds and bound_hits use the reported order. result.optimizer retains SciPy's original solver order, including x and Jacobian columns. To relate them:

reported = result.optimizer.x[list(result.parameter_permutation)]

The permutation and effective parameter bounds are included in result.diagnostics. Custom bounds are permuted with their branch, so bound warnings remain associated with the correct reported parameter.

Load the data first when you want direct access to frequency and impedance arrays:

from eisfit import fit, load_eis

freq, Zexp = load_eis("my_eis.csv")
result = fit(freq, Zexp, tail="warburg")

print(result.parameters)

freq is the frequency array in Hz. Zexp is the measured complex impedance array:

Zexp = Zreal + 1j * Zimag

Input Data

Input files should contain at least three columns:

Quantity Meaning
frequency Frequency in Hz
real impedance Real part of impedance, usually Zreal or Zre
imaginary impedance Imaginary part of impedance, usually Zimag or Zim

Extra columns are allowed. eisfit tries to infer common column names automatically.

Example CSV:

Frequency_Hz,Zreal_Ohm,Zimag_Ohm
100000,0.0182,-0.0014
79432.8,0.0184,-0.0017
63100,0.0187,-0.0021

Models

Default CPE-tail model:

tail = 1 / (Qd * (jω)^nd)
parameters = [L, R0, R1, Q1, n1, R2, Q2, n2, Qd, nd]

Warburg-tail model:

tail = σ / sqrt(jω)
parameters = [L, R0, R1, Q1, n1, R2, Q2, n2, sigma]

The CPE tail keeps the diffusion-like exponent free. The Warburg tail uses the traditional semi-infinite Warburg form.

Command Line

Fit one file:

eisfit my_eis.csv --out-dir outputs --n-starts 40

Use the Warburg tail:

eisfit my_eis.csv --tail warburg --out-dir outputs --n-starts 40

Fit all matching files in a folder:

eisfit my_eis_folder --pattern "*.csv" --out-dir outputs --n-starts 20

Outputs

For each fitted file, eisfit can generate:

  • fitted equivalent-circuit parameters
  • simulated impedance values
  • residuals between measured and fitted impedance
  • Nyquist plot PNG
  • Excel output table for downstream analysis
  • optimizer-attempt audit sheet in the Excel output
  • *_fit_diagnostics.json containing parameters, solver diagnostics and the actual requested fitting configuration, with effective bounds in diagnostics

Demo

The repository includes example EIS files and a demo notebook:

examples/demo_fit_zenodo_dataset.ipynb

You can run the notebook after installing the local development environment:

pip install -e ".[dev]"
jupyter notebook

Development

Run the test suite:

pytest

Run a basic import/compile check:

python -m compileall src tests

Build the package locally:

python -m build

Release

PyPI releases are built from the clean public package branch using GitHub Actions and Trusted Publishing. See RELEASE.md for the release workflow.

License

The package code is released under the MIT License.

Metadata

Release files for eisfit 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for eisfit 0.1.1
File Size Uploaded Provenance Actions
eisfit-0.1.1.tar.gz 13.3 kB With provenance Details for eisfit-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for eisfit 0.1.1
File Interpreter ABI Platform Actions
eisfit-0.1.1-py3-none-any.whl Python 3 none any Details for eisfit-0.1.1-py3-none-any.whl

Total release size: 29.7 kB

Release files / eisfit-0.1.1.tar.gz

Download URL eisfit-0.1.1.tar.gz
Size 13.3 kB
Tags Source
SHA-256 checksum
How to use checksums
c5116e2de559212edc3146977c45838cac38c4417d37f413d7edaf395b108243
BLAKE2b-256 checksum
How to use checksums
374a99eecf577d5d079adc838ba9eb0be39564a230b0e99232dacc5a9466cb35
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release files / eisfit-0.1.1-py3-none-any.whl

Download URL eisfit-0.1.1-py3-none-any.whl
Size 16.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5c46d7b717aa038ef8d5878291eadc28a5860349ef73794a191259fd75518fb6
BLAKE2b-256 checksum
How to use checksums
3dacc2148c210ceff451c9aaf6c1b7dcd997f0127cd6f18c018d56eab9af7b63
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Security for eisfit 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for eisfit-0.1.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page