<jupyter_start><jupyter_text>Comparing cycles of a cyclic voltammagram====================================Here we will show how to use `ixdat` and python to analyze two cases where the difference in integrated current between two cycles in cyclic voltammatry is needed. Using the CO stripping example, we will show three ways of visualizing the stripping experiment and determining the surface area of a platinum electrode. Each gives the amount of charge associated with oxidation of adsorbed CO, and thus an estimate of the electrochemical surface area of the electrode. From most generalized to most automated, they are:- Finding the right timespans, getting the data as numpy vectors with `grab()`, and integrating with `trapz()`- Selecting the data with `CyclicVoltammagram` indexing and `select_sweep()`, and integrating with `integrate()`- Using `subtract()` to get a `CyclicVoltammagramDiff` object that does the analysis.Then, you will, on your own, choose whichever method you like to calculate the amount of charge associated with the reduction of an oxide layer, which gives an estimate of the thickness of the oxide layer. Setup--------We'll use `numpy` and `pathlib.Path` as well as `ixdat`'s `CyclicVoltammagram` measurement type.<jupyter_code>import numpy as np
from pathlib import Path

from ixdat.techniques import CyclicVoltammagram<jupyter_output><empty_output><jupyter_text>Loading raw data----------------------<jupyter_code># Below is An option to load from file. Today we will load from url
# co_strip = CyclicVoltammagram.read(d"../loading_appending_and_saving/co_strip.csv", reader="ixdat")

co_strip = CyclicVoltammagram.read_url(
    "https://raw.githubusercontent.com/ixdat/tutorials/main/loading_appending_and_saving/co_strip.csv",
    reader="ixdat"
)

co_strip.raw_current<jupyter_output><empty_output><jupyter_text>Selecting and calibrating----------------------------------<jupyter_code>co_strip.calibrate(RE_vs_RHE=0.715, A_el=0.196, R_Ohm=100)
help(co_strip.calibrate)
co_strip.grab(co_strip.V_str)
co_strip.plot_measurement()
co_strip.plot()<jupyter_output><empty_output><jupyter_text>Method 1: `grab()` and `np.trapz`-----------------------------------------<jupyter_code>co_strip.plot_measurement(tspan=[180, 220])
co_strip.plot_measurement(tspan=[300, 340])
tspan_strip = [195, 215]
t_strip, I_strip = co_strip.grab("raw_current", tspan=tspan_strip)


tspan_base = [310, 330]
t_base, I_base = co_strip.grab("raw_current", tspan=tspan_base)
print("got these vectors for the strip:")
print(f"t/[s] = {t_strip} \nand \nI/[mA] = {I_strip}")
print()
print(f"they have these shapes: {t_strip.shape} and {I_strip.shape}")
print()
print(f"And for the base, the vectors have shapes: {t_base.shape} and {I_base.shape}")<jupyter_output><empty_output><jupyter_text>**Checking what we've got**<jupyter_code>from matplotlib import pyplot as plt

fig, ax1 = plt.subplots()
ax1.plot(t_strip, I_strip)
ax1.set_xlabel("time / [s]")
ax1.set_ylabel("current / [mA]")
ax1.set_title("stripping current")
fig, ax2 = plt.subplots()
ax2.plot(t_base, I_base, label="base")
ax2.plot(t_strip, I_strip, label="strip")
ax2.legend()
ax2.set_xlabel("time / [s]")
ax2.set_ylabel("current / [mA]")
ax2.set_title("strip and base current vs time")
v_strip = co_strip.grab_for_t("potential", t_strip)
v_base = co_strip.grab_for_t("potential", t_base)

fig, ax = plt.subplots()
ax.plot(v_base, I_base, color="k", label="base")
ax.plot(v_strip, I_strip, color="g", label="strip")
ax.legend()
ax.set_xlabel("potential / [V]")
ax.set_ylabel("current / [mA]")
tspan_base = [311.5, 331.5]
t_base, I_base = co_strip.grab("raw_current", tspan=tspan_base)
v_base = co_strip.grab_for_t("potential", t_base)


fig, ax = plt.subplots()
ax.plot(v_base, I_base, color="k", label="base")
ax.plot(v_strip, I_strip, color="g", label="strip")
ax.legend()
ax.set_xlabel(co_strip.V_str)
ax.set_ylabel("current / [mA]")<jupyter_output><empty_output><jupyter_text>**And do the integration!**<jupyter_code>Q_strip = np.trapz(I_strip, t_strip) * 1e-3  # converts mC --> C

Q_base = np.trapz(I_base, t_base) * 1e-3

Q_CO_ox = Q_strip - Q_base

from ixdat.constants import FARADAY_CONSTANT


#  CO + H2O --> CO2  + 2(H+ + e-)
n_CO_ox = Q_CO_ox / (FARADAY_CONSTANT * 2)

print(f"charge passed = {Q_CO_ox*1e6} uC, corresponding to {n_CO_ox*1e9} nmol of CO oxidized")<jupyter_output><empty_output><jupyter_text>Method 2: Sweep selection and `integrate()`----------------------------------------------------------<jupyter_code>co_strip.plot_measurement(
    J_str="cycle"
)
co_strip.redefine_cycle(start_potential=0.3, redox=False)
co_strip.plot_measurement(J_str="cycle")
co_strip[1].plot()
stripping_cycle = co_strip[1]
base_cycle = co_strip[2]

ax = stripping_cycle.plot(color="green")
base_cycle.plot(ax=ax, color="black")

ax.get_figure().savefig("two_cycles.png")
vspan = [0.6, 1.0]

stripping_sweep = stripping_cycle.select_sweep(vspan=vspan)
base_sweep = base_cycle.select_sweep(vspan=vspan)

stripping_sweep  # to show what you get from this
ax = stripping_sweep.plot(color="g")
base_sweep.plot(color="k", ax=ax)
Q_strip = stripping_sweep.integrate("raw_current", ax="new") * 1e-3
Q_base = base_sweep.integrate("raw_current", ax="new") * 1e-3

Q_CO_ox = Q_strip - Q_base
n_CO_ox = Q_CO_ox / (FARADAY_CONSTANT * 2)

print(f"charge passed = {Q_CO_ox*1e6} uC, corresponding to {n_CO_ox*1e9} nmol of CO oxidized")<jupyter_output><empty_output><jupyter_text>Method 3: `CyclicVoltammagramDiff`------------------------------------------------<jupyter_code>stripping_cycle = co_strip[1]
base_cycle = co_strip[2]

ax = stripping_cycle.plot(color="g")
base_cycle.plot(ax=ax, color="k")
cv_diff = stripping_cycle.diff_with(base_cycle)

cv_diff.plot()
cv_diff.plot_diff()
cv_diff.plot_measurement()
Q_CO_ox = cv_diff.integrate("raw_current", vspan=[0.6, 1.0]) * 1e-3  # 1e-3 converts mC --> C
n_CO_ox = Q_CO_ox / (FARADAY_CONSTANT * 2)

print(f"charge passed = {Q_CO_ox*1e6} uC, corresponding to {n_CO_ox*1e9} nmol of CO oxidized")<jupyter_output><empty_output><jupyter_text>Your turn!========<jupyter_code># oxide_reduction = CyclicVoltammagram.read(data_directory / "oxide_reduction.csv", reader="ixdat")
oxide_reduction = CyclicVoltammagram.read_url(
    "https://raw.githubusercontent.com/ixdat/tutorials/main/loading_appending_and_saving/oxide_reduction.csv",
    reader="ixdat"
)
oxide_reduction.calibrate(RE_vs_RHE=0.715, A_el=0.196, R_Ohm=100)

oxide_reduction.plot_measurement()
oxide_reduction.plot(tspan=[300, 800])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.16441924609255287, 'fraction_numerical': 0.018387986515476556, 'mean_word_length': 5.475198412698413, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 40, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '610586', 'license': 'MIT', 'n_tokens_mistral': 2555, 'n_tokens_neox': 2399, 'n_words': 513, 'path': 'simple_ec_analysis/difference_between_two_cvs.ipynb', 'repo_name': 'ixdat/tutorials', 'size': '6526'}