### Create example directory and launch Jupyter Lab Source: https://impedancepy.readthedocs.io/en/latest/_sources/getting-started.rst.txt Optional: creates a directory for the example project and then starts Jupyter Lab, which opens a new tab in your browser. ```bash mkdir ~/Documents/impedance-example cd ~/Documents/impedance-example ``` ```bash jupyter lab ``` -------------------------------- ### Load libraries Source: https://impedancepy.readthedocs.io/en/latest/examples/model_io_example.html Initial setup importing necessary modules for preprocessing, circuit modeling, visualization, and numerical operations. ```python # Load libraries import impedance.preprocessing as preprocessing import impedance.models.circuits as circuits from impedance.visualization import plot_nyquist import numpy as np import matplotlib.pyplot as plt ``` -------------------------------- ### Install impedance.py with pip Source: https://impedancepy.readthedocs.io/en/latest/_sources/index.rst.txt Install the impedance.py package from PyPI using pip. This is the recommended installation method. ```bash pip install impedance ``` -------------------------------- ### Importing linKK and dependencies Source: https://impedancepy.readthedocs.io/en/latest/_sources/examples/validation_example.ipynb.txt Initial setup to import necessary libraries and the linKK validation module. ```python import matplotlib.pyplot as plt import numpy as np import sys sys.path.append('../../../') from impedance.validation import linKK ``` -------------------------------- ### Install impedance.py and Jupyter Lab Source: https://impedancepy.readthedocs.io/en/latest/getting-started.html Installs impedance.py and its dependencies (scipy, numpy, matplotlib) via pip, and installs Jupyter Lab via conda for the example notebook. ```bash pip install impedance ``` ```bash conda install jupyter jupyterlab ``` -------------------------------- ### Install Miniconda: update conda and verify installation Source: https://impedancepy.readthedocs.io/en/latest/_sources/getting-started.rst.txt Provides essential command-line commands to update conda, list installed packages, and check the Python version after installing Miniconda. A successful conda install should display a package list and report Python version like 'Python 3.x.x :: Anaconda, Inc.'. ```bash conda update conda ``` ```bash conda list ``` ```bash python -V ``` -------------------------------- ### Install Jupyter Lab with conda Source: https://impedancepy.readthedocs.io/en/latest/_sources/getting-started.rst.txt Install Jupyter Lab and Jupyter through conda for interactive EIS analysis. ```bash conda install jupyter jupyterlab ``` -------------------------------- ### Fit a measurement model with CustomCircuit Source: https://impedancepy.readthedocs.io/en/latest/examples/validation_example.html Builds a measurement model with 10 parallel R-C elements, fits it to the example EIS data, and prints the fitted parameters. The circuit string is constructed dynamically and the initial guesses are set with a geometric progression. ```python import matplotlib.pyplot as plt import numpy as np from impedance.models.circuits import CustomCircuit from impedance import preprocessing ``` ```python # Load data from the example EIS result f, Z = preprocessing.readCSV('../../../data/exampleData.csv') # keep only the impedance data in the first quandrant f, Z = preprocessing.ignoreBelowX(f, Z) mask = f < 1000 f = f[mask] Z = Z[mask] ``` ```python N = 10 circuit = 'R_0' initial_guess = [.015] for i in range(N): circuit += f'-p(R_{i % 9 + 1},C_{i % 9 + 1})' initial_guess.append(.03/N) initial_guess.append(10**(3 - 6*i/N)) meas_model = CustomCircuit(initial_guess=initial_guess, circuit=circuit) ``` ```python meas_model.fit(f, Z) print(meas_model) ``` -------------------------------- ### Load template with fitted parameters as initial guesses Source: https://impedancepy.readthedocs.io/en/latest/examples/model_io_example.html Loads a saved model template and sets the fitted_as_initial parameter to True to use previous results as starting guesses. ```python fitted_template = circuits.CustomCircuit() fitted_template.load('fitted_template.json', fitted_as_initial=True) print(fitted_template) ``` -------------------------------- ### Perform Lin-KK fit with linKK Source: https://impedancepy.readthedocs.io/en/latest/examples/validation_example.html Runs the Lin-KK fit with a cutoff value c=0.5, a maximum of 100 RC elements, complex fitting, and an added capacitance. The output shows the number of RC elements (M) and the mu metric, which is 0.31 for this example. ```python M, mu, Z_linKK, res_real, res_imag = linKK(f, Z, c=.5, max_M=100, fit_type='complex', add_cap=True) print('\nCompleted Lin-KK Fit\nM = {:d}\nmu = {:.2f}'.format(M, mu)) ``` -------------------------------- ### Import libraries for measurement model Source: https://impedancepy.readthedocs.io/en/latest/_sources/examples/validation_example.ipynb.txt Imports required for the measurement model example: matplotlib for plotting, numpy, CustomCircuit from impedance.models.circuits, and preprocessing from impedance. ```python import matplotlib.pyplot as plt import numpy as np from impedance.models.circuits import CustomCircuit from impedance import preprocessing ``` -------------------------------- ### Fit new data using previous template Source: https://impedancepy.readthedocs.io/en/latest/examples/model_io_example.html Fits the shifted data Z2 using the previously fitted template as a starting point and plots the results. ```python fig, ax = plt.subplots(figsize=(10,10)) f_pred = np.logspace(5,-2) fitted_template.fit(frequencies, Z2) imported_circuit_init = fitted_template.predict(f_pred, use_initial = True) imported_circuit_fit = fitted_template.predict(f_pred) plot_nyquist(ax, Z) plot_nyquist(ax, Z2) plot_nyquist(ax, imported_circuit_init) plot_nyquist(ax, imported_circuit_fit) ax.legend(['Original Data', 'Shifted Data', 'Template Initial', 'Loaded Template Fit']) plt.show() print(fitted_template) ``` -------------------------------- ### Find .z files matching Circuit*EIS* pattern Source: https://impedancepy.readthedocs.io/en/latest/examples/looping_files_example.html Uses glob with a pattern that matches .z files starting with 'Circuit' and containing 'EIS' to list all matching files in the data directory. The output shows the six files found. ```python directory = r'../../../data/' all_files = glob.glob(os.path.join(directory, 'Circuit*EIS*.z')) all_files ``` ```output ['../../../data/Circuit3_EIS_1.z', '../../../data/Circuit1_EIS_2.z', '../../../data/Circuit2_EIS_1.z', '../../../data/Circuit3_EIS_2.z', '../../../data/Circuit1_EIS_1.z', '../../../data/Circuit2_EIS_2.z'] ``` -------------------------------- ### Randles circuit setup and validation Source: https://impedancepy.readthedocs.io/en/latest/_modules/impedance/models/circuits/circuits.html Sets the circuit name and string for a Randles circuit, optionally with a constant phase element (CPE). Then validates that the number of initial guesses plus constants matches the circuit length, raising a ValueError otherwise. ```python if CPE: self.name = 'Randles w/ CPE' self.circuit = 'R0-p(R1-Wo1,CPE1)' else: self.name = 'Randles' self.circuit = 'R0-p(R1-Wo1,C1)' circuit_len = calculateCircuitLength(self.circuit) if len(self.initial_guess) + len(self.constants) != circuit_len: raise ValueError('The number of initial guesses ' + f'({len(self.initial_guess)}) + ' + 'the number of constants ' + f'({len(self.constants)})' + ' must be equal to ' + f'the circuit length ({circuit_len})') ``` -------------------------------- ### Create and fit circuit models Source: https://impedancepy.readthedocs.io/en/latest/_sources/examples/looping_files_example.ipynb.txt Initializes CustomCircuit objects for each dataset and performs the fitting process. ```python from impedance.models.circuits import CustomCircuit # This data comes from dummy circuits I made to check measurement bias in # our potentiostat, so I know a priori its an R-RC circuit circuits = [] circ_string = 'R0-p(R1,C1)' initial_guess = [100, 400, 1e-5] # Now loop through data list to create circuits and fit them for f, Z, filename in zip(freqs, Zs, all_files): name = filename.split('/')[-1] circuit = CustomCircuit(circ_string, initial_guess=initial_guess, name=name) circuit.fit(f, Z) circuits.append(circuit) ``` -------------------------------- ### Create CustomCircuit with circuit string and initial guesses (impedance.py) Source: https://impedancepy.readthedocs.io/en/latest/_sources/getting-started.rst.txt Import the CustomCircuit object, define the circuit string using the syntax of series elements with '-' and parallel elements with 'p( , )', provide an initial guess list in parameter definition order, and instantiate the circuit. ```python from impedance.models.circuits import CustomCircuit circuit = 'R0-p(R1,C1)-p(R2-Wo1,C2)' initial_guess = [.01, .01, 100, .01, .05, 100, 1] circuit = CustomCircuit(circuit, initial_guess=initial_guess) ``` -------------------------------- ### Loop over data files to create and fit CustomCircuit objects Source: https://impedancepy.readthedocs.io/en/latest/examples/looping_files_example.html Creates a list of CustomCircuit objects from a list of impedance data files, fitting each with the same circuit string and initial guess. The loop uses zip over frequencies, impedance data, and filenames, and stores the fitted circuits in a list. ```python from impedance.models.circuits import CustomCircuit # This data comes from dummy circuits I made to check measurement bias in # our potentiostat, so I know a priori its an R-RC circuit circuits = [] circ_string = 'R0-p(R1,C1)' initial_guess = [100, 400, 1e-5] # Now loop through data list to create circuits and fit them for f, Z, filename in zip(freqs, Zs, all_files): name = filename.split('/')[-1] circuit = CustomCircuit(circ_string, initial_guess=initial_guess, name=name) circuit.fit(f, Z) circuits.append(circuit) ``` -------------------------------- ### Import impedance data with preprocessing.readCSV Source: https://impedancepy.readthedocs.io/en/latest/getting-started.html Loads impedance data from a CSV file with columns frequency, Z_real, and Z_imag, then filters to keep only data in the first quadrant. Requires the file exampleData.csv in the current working directory. ```python from impedance import preprocessing # Load data from the example EIS data frequencies, Z = preprocessing.readCSV('./exampleData.csv') # keep only the impedance data in the first quandrant frequencies, Z = preprocessing.ignoreBelowX(frequencies, Z) ``` -------------------------------- ### readCHInstruments function Source: https://impedancepy.readthedocs.io/en/latest/_modules/impedance/preprocessing.html Reads impedance data from a CHInstruments .txt file. It locates the data starting after the 'Freq/Hz' header. ```python def readCHInstruments(filename): """ function for reading the .txt file from CHInstruments Parameters ---------- filename: string Filename of .txt file to extract impedance data from Returns ------- frequencies : np.ndarray Array of frequencies impedance : np.ndarray of complex numbers Array of complex impedances """ with open(filename, 'r') as input_file: lines = input_file.readlines() # Locate the line where the data lives for i, line in enumerate(lines): if line.startswith('Freq/Hz'): # CH instruments has an empty space b/w header # and start of data line start_line = i+2 raw_data = lines[start_line:] f, Z = [], [] for line in raw_data: each = line.split(',') f.append(float(each[0])) Z.append(complex(float(each[1]), float(each[2]))) return np.array(f), np.array(Z) ``` -------------------------------- ### Import visualization tools Source: https://impedancepy.readthedocs.io/en/latest/_sources/examples/looping_files_example.ipynb.txt Import matplotlib and the impedance visualization functions for plotting. ```python import matplotlib.pyplot as plt from impedance.visualization import plot_nyquist, plot_bode ``` -------------------------------- ### Import required libraries for impedance plotting Source: https://impedancepy.readthedocs.io/en/latest/examples/plotting_example.html Imports matplotlib, numpy, CustomCircuit, and preprocessing modules needed for the examples on this page. ```python import matplotlib.pyplot as plt import numpy as np from impedance.models.circuits import CustomCircuit from impedance import preprocessing ``` -------------------------------- ### BaseCircuit.__init__ Source: https://impedancepy.readthedocs.io/en/latest/_modules/impedance/models/circuits/circuits.html Constructor for any equivalent circuit model. Initializes the circuit with an initial guess, optional constants, and a name. ```APIDOC ## BaseCircuit.__init__ ### Description Initializes a BaseCircuit instance with an initial guess, optional constants, and a name. ### Method Constructor ### Parameters - **initial_guess** (numpy array) - Optional - Initial guess of the circuit values. - **constants** (dict, optional) - Optional - Parameters and values to hold constant during fitting (e.g. {"R0": 0.1}). - **name** (str, optional) - Optional - Name for the circuit. ### Returns None ``` -------------------------------- ### Load and filter EIS data Source: https://impedancepy.readthedocs.io/en/latest/_sources/examples/validation_example.ipynb.txt Loads example EIS data from a CSV file, filters to the first quadrant using ignoreBelowX, and keeps only frequencies below 1000 Hz. ```python # Load data from the example EIS result f, Z = preprocessing.readCSV('../../../data/exampleData.csv') # keep only the impedance data in the first quandrant f, Z = preprocessing.ignoreBelowX(f, Z) mask = f < 1000 f = f[mask] Z = Z[mask] ``` -------------------------------- ### Create and save a circuit template Source: https://impedancepy.readthedocs.io/en/latest/_sources/examples/model_io_example.ipynb.txt Creates a custom circuit with initial guesses, prints it, and saves it as a JSON template using the `circuit.save()` function. ```python test_circuit = circuits.CustomCircuit(initial_guess=[.01, .005, .1, .005, .1, .001, 200], circuit='R0-p(R1,C1)-p(R2,C2)-Wo1') print(test_circuit) test_circuit.save('template_model.json') ``` -------------------------------- ### readVersaStudio(filename) Source: https://impedancepy.readthedocs.io/en/latest/preprocessing.html Reads the .PAR file from VersaStudio. ```APIDOC ## readVersaStudio(filename) ### Description Function for reading the .PAR file from VersaStudio. ### Method Function call ### Endpoint impedance.preprocessing.readVersaStudio ### Parameters - **filename** (string) - Required - Filename of .PAR file to extract impedance data from ### Returns - **frequencies** (np.ndarray) - Array of frequencies - **impedance** (np.ndarray of complex numbers) - Array of complex impedances ``` -------------------------------- ### Importing circuit models Source: https://impedancepy.readthedocs.io/en/latest/examples/fitting_example.html Import the Randles and CustomCircuit classes from the impedance package. ```python from impedance.models.circuits import Randles, CustomCircuit ``` -------------------------------- ### fit_linKK function definition (partial) Source: https://impedancepy.readthedocs.io/en/latest/_modules/impedance/validation.html Starts the definition of the fit_linKK function that fits the Lin-KK model using linear regression. The function signature and docstring are shown; the body is not displayed in the source. ```python def fit_linKK(f, ts, M, Z, fit_type='real', add_cap=False): """ Fits the linKK model using linear regression ``` -------------------------------- ### BaseCircuit.load Source: https://impedancepy.readthedocs.io/en/latest/circuits.html Imports a model from JSON. ```APIDOC ## BaseCircuit.load ### Description Imports a model from JSON. ### Method load ### Signature load(filepath, fitted_as_initial=False) ### Parameters - **filepath** (str) - Required - filepath to JSON file to load model from - **fitted_as_initial** (bool) - Optional - If true, loads the model's fitted parameters as initial guesses. Otherwise, loads the model's initial and fitted parameters as a completed model ``` -------------------------------- ### Load and preprocess EIS data Source: https://impedancepy.readthedocs.io/en/latest/examples/validation_example.html Loads example EIS data from a CSV file, filters out points with negative real impedance, and keeps only frequencies below 1000 Hz. The resulting f and Z arrays are used as input for the Lin-KK fit. ```python # Load data from the example EIS result f, Z = preprocessing.readCSV('../../../data/exampleData.csv') # keep only the impedance data in the first quandrant f, Z = preprocessing.ignoreBelowX(f, Z) mask = f < 1000 f = f[mask] Z = Z[mask] ``` -------------------------------- ### Fit a custom circuit to impedance data Source: https://impedancepy.readthedocs.io/en/latest/examples/plotting_example.html Creates a CustomCircuit with an initial guess and circuit string, fits it to the data, and prints the circuit details. The output shows the circuit string, fit status, initial guesses, and fitted parameters with uncertainties. ```python circuit = CustomCircuit(initial_guess=[.01, .005, .1, .005, .1, .001, 200], circuit='R_0-p(R_1,C_1)-p(R_1,C_1)-Wo_1') circuit.fit(frequencies, Z) print(circuit) ``` ```text Circuit string: R_0-p(R_1,C_1)-p(R_1,C_1)-Wo_1 Fit: True Initial guesses: R_0 = 1.00e-02 [Ohm] R_1 = 5.00e-03 [Ohm] C_1 = 1.00e-01 [F] R_1 = 5.00e-03 [Ohm] C_1 = 1.00e-01 [F] Wo_1_0 = 1.00e-03 [Ohm] Wo_1_1 = 2.00e+02 [sec] Fit parameters: R_0 = 1.65e-02 (+/- 1.54e-04) [Ohm] R_1 = 5.31e-03 (+/- 2.06e-04) [Ohm] C_1 = 2.32e-01 (+/- 1.90e-02) [F] R_1 = 8.77e-03 (+/- 1.89e-04) [Ohm] C_1 = 3.28e+00 (+/- 1.85e-01) [F] Wo_1_0 = 6.37e-02 (+/- 2.03e-03) [Ohm] Wo_1_1 = 2.37e+02 (+/- 1.72e+01) [sec] ``` -------------------------------- ### load method: import model from JSON Source: https://impedancepy.readthedocs.io/en/latest/_modules/impedance/models/circuits/circuits.html Loads a model from a JSON file. Reads the circuit string, initial guess, constants, and name. If the JSON indicates a fit, either uses the fitted parameters as initial guesses (when fitted_as_initial is True) or sets them as the model's fitted parameters and confidence intervals. ```python json_data_file = open(filepath, 'r') json_data = json.load(json_data_file) model_name = json_data["Name"] model_string = json_data["Circuit String"] model_initial_guess = json_data["Initial Guess"] model_constants = json_data["Constants"] self.initial_guess = model_initial_guess self.circuit = model_string print(self.circuit) self.constants = model_constants self.name = model_name if json_data["Fit"]: if fitted_as_initial: self.initial_guess = np.array(json_data['Parameters']) else: self.parameters_ = np.array(json_data["Parameters"]) self.conf_ = np.array(json_data["Confidence"]) ``` -------------------------------- ### Create and activate conda environment Source: https://impedancepy.readthedocs.io/en/latest/_sources/getting-started.rst.txt Creates a conda environment with Python 3 and activates it with name 'impedance-analysis'. ```bash conda create -n impedance-analysis python=3 ``` ```bash conda activate impedance-analysis ``` -------------------------------- ### Initializing Randles circuit Source: https://impedancepy.readthedocs.io/en/latest/examples/fitting_example.html Initialize Randles circuit instances with initial parameter guesses, optionally enabling a constant phase element (CPE). ```python randles = Randles(initial_guess=[.01, .005, .001, 200, .1]) randlesCPE = Randles(initial_guess=[.01, .005, .001, 200, .1, .9], CPE=True) ``` -------------------------------- ### Import model from JSON Source: https://impedancepy.readthedocs.io/en/latest/examples/model_io_example.html Loads a previously saved circuit model template from a JSON file into a new CustomCircuit instance. ```python loaded_template = circuits.CustomCircuit() loaded_template.load('template_model.json') print("Loaded Template") print(loaded_template) ``` -------------------------------- ### Fit Equivalent Circuits to Spectrum Source: https://impedancepy.readthedocs.io/en/latest/examples/fitting_example.html Execute the .fit() method on circuit objects to determine parameters, followed by printing the circuit object to view fit results. ```python randles.fit(frequencies, Z) randlesCPE.fit(frequencies, Z) customCircuit.fit(frequencies, Z) customConstantCircuit.fit(frequencies, Z) print(customConstantCircuit) ``` ```text Circuit string: R_0-p(R_1,C_1)-p(R_2,C_2)-Wo_1 Fit: True Constants: R_0 = 2.00e-02 [Ohm] Wo_1_1 = 2.00e+02 [sec] Initial guesses: R_1 = 5.00e-03 [Ohm] C_1 = 1.00e-01 [F] R_2 = 5.00e-03 [Ohm] C_2 = 1.00e-01 [F] Wo_1_0 = 1.00e-03 [Ohm] Fit parameters: R_1 = 6.79e-03 (+/- 1.08e-03) [Ohm] C_1 = 5.62e+00 (+/- 1.96e+00) [F] R_2 = 3.91e-03 (+/- 1.09e-03) [Ohm] C_2 = 1.36e+00 (+/- 2.61e-01) [F] Wo_1_0 = 5.88e-02 (+/- 1.25e-03) [Ohm] ``` -------------------------------- ### Fit data using an imported template model Source: https://impedancepy.readthedocs.io/en/latest/examples/model_io_example.html Uses a loaded template to fit data and visualize the initial versus fitted circuit response on a Nyquist plot. ```python fig, ax = plt.subplots(figsize=(5,5)) f_pred = np.logspace(5,-2) loaded_template.fit(frequencies, Z) imported_circuit_init = loaded_template.predict(f_pred, use_initial = True) imported_circuit_fit = loaded_template.predict(f_pred) plot_nyquist(ax, Z) plot_nyquist(ax, imported_circuit_init) plot_nyquist(ax, imported_circuit_fit) ax.legend(['Data', 'Loaded Template Initial', 'Loaded Template Fit']) plt.show() print(loaded_template) ``` -------------------------------- ### Construct measurement model circuit Source: https://impedancepy.readthedocs.io/en/latest/_sources/examples/validation_example.ipynb.txt Builds a measurement model circuit with 10 parallel R-C elements and initial guesses, then creates a CustomCircuit instance. ```python N = 10 circuit = 'R_0' initial_guess = [.015] for i in range(N): circuit += f'-p(R_{i % 9 + 1},C_{i % 9 + 1})' initial_guess.append(.03/N) initial_guess.append(10**(3 - 6*i/N)) meas_model = CustomCircuit(initial_guess=initial_guess, circuit=circuit) ``` -------------------------------- ### Print fitted circuits and their output Source: https://impedancepy.readthedocs.io/en/latest/examples/looping_files_example.html Prints each fitted circuit object, showing the circuit name, circuit string, fit status, initial guesses, and fit parameters with uncertainties. The output demonstrates the expected similarity among replicates of the same circuit. ```python for circuit in circuits: print(circuit) ``` ```text Name: Circuit3_EIS_1.z Circuit string: R0-p(R1,C1) Fit: True Initial guesses: R0 = 1.00e+02 [Ohm] R1 = 4.00e+02 [Ohm] C1 = 1.00e-05 [F] Fit parameters: R0 = 1.51e+03 (+/- 2.62e+00) [Ohm] R1 = 4.63e+03 (+/- 3.14e+00) [Ohm] C1 = 2.02e-08 (+/- 5.39e-11) [F] Name: Circuit1_EIS_2.z Circuit string: R0-p(R1,C1) Fit: True Initial guesses: R0 = 1.00e+02 [Ohm] R1 = 4.00e+02 [Ohm] C1 = 1.00e-05 [F] Fit parameters: R0 = 2.91e+01 (+/- 3.63e-02) [Ohm] R1 = 4.67e+01 (+/- 4.69e-02) [Ohm] C1 = 1.04e-05 (+/- 2.95e-08) [F] Name: Circuit2_EIS_2.z Circuit string: R0-p(R1,C1) Fit: True Initial guesses: R0 = 1.00e+02 [Ohm] R1 = 4.00e+02 [Ohm] C1 = 1.00e-05 [F] Fit parameters: R0 = 1.50e+02 (+/- 3.19e-01) [Ohm] R1 = 5.02e+02 (+/- 3.53e-01) [Ohm] C1 = 3.12e-08 (+/- 7.70e-11) [F] ``` -------------------------------- ### Performing Lin-KK fit Source: https://impedancepy.readthedocs.io/en/latest/_sources/examples/validation_example.ipynb.txt Executing the linKK fit with specified parameters and printing the resulting M and mu values. ```python M, mu, Z_linKK, res_real, res_imag = linKK(f, Z, c=.5, max_M=100, fit_type='complex', add_cap=True) print('\nCompleted Lin-KK Fit\nM = {:d}\nmu = {:.2f}'.format(M, mu)) ``` -------------------------------- ### circuit_fit(frequencies, impedances, circuit, initial_guess, constants={}, bounds=None, weight_by_modulus=False, global_opt=False, **kwargs) Source: https://impedancepy.readthedocs.io/en/latest/fitting.html Main function for fitting an equivalent circuit to data. By default, uses scipy.optimize.curve_fit; optionally uses scipy.optimize.basinhopping for global optimization. ```APIDOC ## circuit_fit(frequencies, impedances, circuit, initial_guess, constants={}, bounds=None, weight_by_modulus=False, global_opt=False, **kwargs) ### Description Main function for fitting an equivalent circuit to data. By default, this function uses scipy.optimize.curve_fit to fit the equivalent circuit. This function generally works well for simple circuits. However, the final results may be sensitive to the initial conditions for more complex circuits. In these cases, the scipy.optimize.basinhopping global optimization algorithm can be used to attempt a better fit. ### Parameters - **frequencies** (numpy array) - Required - Frequencies. - **impedances** (numpy array of dtype 'complex128') - Required - Impedances. - **circuit** (string) - Required - String defining the equivalent circuit to be fit. - **initial_guess** (list of floats) - Required - Initial guesses for the fit parameters. - **constants** (dictionary, optional) - Optional - Parameters and their values to hold constant during fitting (e.g. {"RO": 0.1}). Defaults to {}. - **bounds** (2-tuple of array_like, optional) - Optional - Lower and upper bounds on parameters. Defaults to bounds on all parameters of 0 and np.inf, except the CPE alpha which has an upper bound of 1. - **weight_by_modulus** (bool, optional) - Optional - Uses the modulus of each data (|Z|) as the weighting factor. Standard weighting scheme when experimental variances are unavailable. Only applicable when global_opt = False. - **global_opt** (bool, optional) - Optional - If global optimization should be used (uses the basinhopping algorithm). Defaults to False. - **kwargs** - Optional - Keyword arguments passed to scipy.optimize.curve_fit or scipy.optimize.basinhopping. ### Returns - **p_values** (list of floats) - Best fit parameters for specified equivalent circuit. - **p_errors** (list of floats) - One standard deviation error estimates for fit parameters. ### Notes Need to do a better job of handling errors in fitting. Currently, an error of -1 is returned. ``` -------------------------------- ### Fit the circuit to impedance data Source: https://impedancepy.readthedocs.io/en/latest/_sources/getting-started.rst.txt Calls the .fit() method with experimental frequencies and impedance Z to fit the model. The fitted parameters are available via .parameters_ or by printing the circuit object. ```python circuit.fit(frequencies, Z) ``` -------------------------------- ### Fit circuit models and print custom constant circuit Source: https://impedancepy.readthedocs.io/en/latest/_sources/examples/fitting_example.ipynb.txt Fits four circuit models to the same impedance data and prints the custom constant circuit. The output shows the circuit string, fit status, constants, initial guesses, and fitted parameters with uncertainties. ```python randles.fit(frequencies, Z) randlesCPE.fit(frequencies, Z) customCircuit.fit(frequencies, Z) customConstantCircuit.fit(frequencies, Z) print(customConstantCircuit) ``` -------------------------------- ### readPowerSuite(filename) Source: https://impedancepy.readthedocs.io/en/latest/preprocessing.html Reads the .txt file from PowerSuite. ```APIDOC ## readPowerSuite(filename) ### Description Function for reading the .txt file from PowerSuite. ### Method Function call ### Endpoint impedance.preprocessing.readPowerSuite ### Parameters - **filename** (string) - Required - Filename of .txt file to extract impedance data from ### Returns - **frequencies** (np.ndarray) - Array of frequencies - **impedance** (np.ndarray of complex numbers) - Array of complex impedances ``` -------------------------------- ### Initialize circuit_elements dictionary Source: https://impedancepy.readthedocs.io/en/latest/_modules/impedance/models/circuits/elements.html Initializes the circuit_elements dictionary with the series and parallel operators, which are not decorated with metadata. ```python circuit_elements = {"s": s, "p": p} ``` -------------------------------- ### eval_linKK: build and evaluate RC circuit Source: https://impedancepy.readthedocs.io/en/latest/_modules/impedance/validation.html Builds a circuit string from elements, time constants, and frequencies, then evaluates it using circuit_elements. Used for LinKK fitting. ```python def eval_linKK(elements, ts, f): """Builds a circuit of RC elements to be used in LinKK""" elements_list = elements.tolist() ts_list = ts.tolist() f_list = f.tolist() circuit_string = f"s([R({[elements_list[0]]},{f_list})," for Rk, tk in zip(elements_list[1:], ts_list): circuit_string += f"K({[Rk, tk]},{f_list})," circuit_string += f"L({[elements_list[-1]]},{f_list})," if len(elements_list) == (len(ts_list) + 3): circuit_string += f"C({[1 / elements_list[-2]]},{f_list})," circuit_string = circuit_string.strip(',') circuit_string += '])' return eval(circuit_string, circuit_elements) ``` -------------------------------- ### Import EIS data from CSV with impedance.preprocessing Source: https://impedancepy.readthedocs.io/en/latest/_sources/getting-started.rst.txt Loads EIS data from a CSV file with columns frequency, Z_real, and Z_imag, then retains only the impedance data in the first quadrant using preprocessing.readCSV and ignoreBelowX. ```python from impedance import preprocessing # Load data from the example EIS data frequencies, Z = preprocessing.readCSV('./exampleData.csv') # keep only the impedance data in the first quandrant frequencies, Z = preprocessing.ignoreBelowX(frequencies, Z) ```