Skip to content

Commit

Permalink
Add basic support for EIS
Browse files Browse the repository at this point in the history
  • Loading branch information
WardLT committed Feb 26, 2024
1 parent 2e8e2e2 commit 08d31e8
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
36 changes: 36 additions & 0 deletions batdata/schemas/eis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""Schemas associated with Electrochemical Impedance Spectroscopy"""

from typing import List

from pandas import DataFrame
from pydantic import Field
import numpy as np

from .cycling import ColumnSchema


class EISData(ColumnSchema):
"""Measurements for a specific EIS test"""

test_time: List[float] = Field(None, description="Time from the beginning of the cycling test. Times must be "
"nonnegative and monotonically increasing. Units: s",
monotonic=True)
time: List[float] = Field(None, description="Time as a UNIX timestamp. Assumed to be in UTC")
frequency: List[float] = Field(..., description="Applied frequency. Units: Hz")
z_real: List[float] = Field(..., description="Real component of impedance. Units: Ohm")
z_imag: List[float] = Field(..., description="Imaginary component of impedance. Units: Ohm")
z_mag: List[float] = Field(..., description="Magnitude of impedance. Units: Ohm")
z_phase: List[float] = Field(..., description="Phase angle of the impedance. Units: Degree")

@classmethod
def validate_dataframe(cls, data: DataFrame, allow_extra_columns: bool = True):
# Check that the schema is supported
super().validate_dataframe(data, allow_extra_columns)

# Ensure that the cartesian coordinates for the impedance agree with the magnitude
z_real_from_polar = np.multiply(data['z_mag'], np.cos(np.deg2rad(data['z_phase'])))
z_imag_from_polar = np.multiply(data['z_mag'], np.sin(np.deg2rad(data['z_phase'])))
if not np.isclose(z_real_from_polar, data['z_real'], rtol=0.01).all():
raise ValueError('Polar and cartesian forms of impedance disagree for real component')
if not np.isclose(z_imag_from_polar, data['z_imag'], rtol=0.01).all():
raise ValueError('Polar and cartesian forms of impedance disagree for imaginary component')
33 changes: 33 additions & 0 deletions tests/schemas/test_eis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from pytest import fixture, raises
import pandas as pd
import numpy as np

from batdata.schemas.eis import EISData


@fixture()
def example_df() -> pd.DataFrame:
output = pd.DataFrame({
'frequency': [5e5, 4e5],
'z_real': [0.241, 0.237],
'z_imag': [0.431, 0.327],
})
output['z_mag'] = np.linalg.norm(output.values[:, -2:], axis=1)
output['z_phase'] = np.rad2deg(np.arcsin(output['z_imag'] / output['z_mag']))
return output


def test_pass(example_df):
EISData.validate_dataframe(example_df)


def test_consistency(example_df):
example_df['z_imag'] *= 2
with raises(ValueError) as e:
EISData.validate_dataframe(example_df)
assert 'imaginary' in str(e.value)

example_df['z_real'] *= 2
with raises(ValueError) as e:
EISData.validate_dataframe(example_df)
assert 'real' in str(e.value)

0 comments on commit 08d31e8

Please sign in to comment.