Skip to content
Snippets Groups Projects
Commit bbcdb239 authored by Felix Thelen's avatar Felix Thelen
Browse files

Now the interpolation function should also be accessible for the SECCM analysis

parent 55d46f59
Branches
No related tags found
No related merge requests found
from .interp import *
\ No newline at end of file
File moved
from .loading import *
from .interp import *
from ..general import *
from .plotting import plot_lsvs, plot_pots_on_wafer, plot_curs_on_wafer, save_lsv_plots
from .plotting import plot_pots_on_wafer
......@@ -2,7 +2,7 @@ import matplotlib.pyplot as plt
import pandas as pd
from pathlib import Path
from .interp import cur_dens_at_pot, pot_at_cur_dens
from ..general import cur_dens_at_pot, pot_at_cur_dens
def plot_lsvs(lsvs: dict[int, pd.DataFrame] | pd.DataFrame, title: str, excl_mas: list[int] = None, ymin: float = None,
......
from .loading import *
from ..general import *
from .plotting import plot_lsvs, plot_curs_on_wafer
import pandas as pd
import numpy as np
# :- General function
def interpolate_lsv(lsv: pd.DataFrame | dict[int, pd.DataFrame],
pot: float | list | np.ndarray = None,
cur: float | list | np.ndarray = None) -> float | np.ndarray | dict[int, pd.DataFrame | float]:
"""
General function to interpolate a single LSV or a dictionary of LSVs. If a single or multiple current density values
should be interpolated at a specified potential or potentials, define the "pot" parameter. If a single or multiple
potentials should be interpolated at a specified current density or densities, use the "cur" parameter. Depending on
the input types, the output type changes. In case a single LSV should be interpolated at a single value, also a
single value is returned. If a single LSV should be interpolated at multiple target values, a numpy array of the
same size is returned. If multiple LSVs should be interpolated, the output is a dictionary of floats or DataFrames
depending on whether one or multiple target values (potentials or currents) were provided.
:param lsv: LSV(s) to interpolate
:param pot: potential(s) at which the current density(ies) should be interpolated
:param cur: current density(ies) at which the potential(s) should be interpolated
:return: interpolated current density(ies) or potential(s)
"""
# Check if either the potentials or current densities were set and raise an error if not
if pot is None and cur is None:
raise ValueError('Either the potential(s) or current density(ies) need to be set.')
# If just one LSV was given, wrap it inside a dictionary
lsvs = {0: lsv} if isinstance(lsv, pd.DataFrame) else lsv
# If just one potential or current needs to be extracted, wrap it inside a numpy array
target = cur if pot is None else pot
v_interp = target if isinstance(target, list) or isinstance(target, np.ndarray) else np.array(target)
# Extract the DataFrame column header to return the data with the same headers
columns = list(lsvs.values())[0].columns
# Create an empty dictionary to store the results in
res: dict[int, pd.DataFrame] = {}
# Iterate over all LSVs by measurement area
for ma, data in lsvs.items():
# For the linear interpolation, the values need to monotonically increase
# Therefore check if the order datapoints is reversed, which occurs with HER and ORR
# Checking the difference of all datapoints can lead to wrong results, because there can be small changes in
# direction. If more than half of the order of values are reversed, the order is inferred as reversed
is_reversed = np.sum(np.diff(data.iloc[:, 0]) < 0) > (len(data) - 1) / 2
# Flip the data if necessary
values = np.flip(data.values, axis=0) if is_reversed else data.values
# If the current densities need to be interpolated, flip the order of the columns
values = np.flip(values, axis=1) if cur is not None else values
# Perform the interpolation, interpolate either the x or y values
res_interp = np.interp(v_interp, values[:, 0], values[:, 1])
# Add potentials and current densities back together
result = np.vstack((v_interp, res_interp)).T
# If the current densities need to be interpolated, flip the order of the columns
result = np.flip(result, axis=1) if pot is None else result
# Add the results to the dictionary as a DataFrame
res[ma] = pd.DataFrame(result, columns=columns)
# Define the column index of the target value
t_ind = 0 if pot is None else 1
# Return the interpolated result, the type depends on the input parameter types
if isinstance(lsv, pd.DataFrame):
# If a single LSV was given and multiple values were interpolated, return a numpy array with all interpolated
# values
if isinstance(target, np.ndarray) or isinstance(target, list):
return res[0].iloc[:, t_ind].values
# If a single LSV was given and only a single value was interpolated, return a float of the interpolated value
else:
return res[0].iloc[0, t_ind]
# If multiple LSVs were provided, return either a dictionary of floats or of pandas DataFrames
else:
# If multiple values were interpolated, return a dictionary of DataFrames
if isinstance(target, np.ndarray) or isinstance(target, list):
return res
# If only a singe value was interpolated, return a dictionary of floats
else:
return {ma: _lsv.iloc[0, t_ind] for ma, _lsv in res.items()}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment