In [1]:
Copied!
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from mxlpy import Assimulo, Simulator, make_protocol, unwrap
from mxlbricks import names as n
from mxlbricks.models import get_saadat2021
def get_npq(ppfd: pd.Series, fluorescence: pd.Series) -> pd.Series:
"""Calculates the non-photochemical quenching from the extracted
important points of the PAM simulations
Returns
-------
Fm: Fm (first element of list) and Fm' values
NPQ: Calculated NPQ values
tm: Exact time points of peaks in PAM trace
Fo: Fo (first element of list) and Ft' values
to: Exact time points of Fo and Ft' values
"""
# container for lists. Each list contains the positions of fluorescence values for one peak
# container for position of Fo'
z = []
o = []
light = ppfd.to_numpy()
t = ppfd.index.to_numpy()
fluorescence = fluorescence.to_numpy()
max_light = max(light)
cnt = 0
while cnt < len(light):
if light[cnt] == max_light:
# temporary container for all F==maxlight. For each peak it is renewed
h = []
while cnt != len(light) and light[cnt] == max(light):
h.append(cnt)
cnt += 1
z.append(h)
o.append(h[0] - 1) # value directly at the bottom of peak is Fo
else:
cnt += 1
# Fm is the maximal value for each peak sequence
peaks = [i[np.argmax(fluorescence[i])] for i in z]
Fm = fluorescence[peaks]
return pd.Series((Fm[0] - Fm) / Fm, name="NPQ", index=t[peaks])
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from mxlpy import Assimulo, Simulator, make_protocol, unwrap
from mxlbricks import names as n
from mxlbricks.models import get_saadat2021
def get_npq(ppfd: pd.Series, fluorescence: pd.Series) -> pd.Series:
"""Calculates the non-photochemical quenching from the extracted
important points of the PAM simulations
Returns
-------
Fm: Fm (first element of list) and Fm' values
NPQ: Calculated NPQ values
tm: Exact time points of peaks in PAM trace
Fo: Fo (first element of list) and Ft' values
to: Exact time points of Fo and Ft' values
"""
# container for lists. Each list contains the positions of fluorescence values for one peak
# container for position of Fo'
z = []
o = []
light = ppfd.to_numpy()
t = ppfd.index.to_numpy()
fluorescence = fluorescence.to_numpy()
max_light = max(light)
cnt = 0
while cnt < len(light):
if light[cnt] == max_light:
# temporary container for all F==maxlight. For each peak it is renewed
h = []
while cnt != len(light) and light[cnt] == max(light):
h.append(cnt)
cnt += 1
z.append(h)
o.append(h[0] - 1) # value directly at the bottom of peak is Fo
else:
cnt += 1
# Fm is the maximal value for each peak sequence
peaks = [i[np.argmax(fluorescence[i])] for i in z]
Fm = fluorescence[peaks]
return pd.Series((Fm[0] - Fm) / Fm, name="NPQ", index=t[peaks])
Figure 2: Simulated PAM fluorescence trace¶
In [2]:
Copied!
protocol = make_protocol(
[
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
]
)
protocol = make_protocol(
[
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 1000}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
(120, {n.pfd(): 50}),
(0.8, {n.pfd(): 5000}),
]
)
In [3]:
Copied!
res = unwrap(
Simulator(
get_saadat2021().update_parameter("kf_cyclic_electron_flow", 0),
integrator=Assimulo,
)
.simulate_protocol(protocol)
.get_result()
)
res = unwrap(
Simulator(
get_saadat2021().update_parameter("kf_cyclic_electron_flow", 0),
integrator=Assimulo,
)
.simulate_protocol(protocol)
.get_result()
)
In [4]:
Copied!
args = res.get_args(include_parameters=True, include_readouts=True)
fluo = args.loc[:, n.fluorescence()]
npq = get_npq(args.loc[:, n.pfd()], fluo)
args = res.get_args(include_parameters=True, include_readouts=True)
fluo = args.loc[:, n.fluorescence()]
npq = get_npq(args.loc[:, n.pfd()], fluo)
In [5]:
Copied!
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(fluo / fluo.max(), color="red", lw=2, label="Fluorescence")
ax.plot(npq, linestyle="dashed", color="black", lw=2, label="NPQ")
ax.axvspan(0, 2 * 120, color=(0, 0, 0, 1 / 4))
ax.axvspan(12 * 120, 21 * 120, color=(0, 0, 0, 1 / 4))
ax.set(
ylim=(0, 1.1),
xlim=(0, 2500),
xlabel="Time/(s)",
ylabel="Fluorescence (normalised)",
)
ax.legend(loc="lower right")
ax.grid(visible=True)
plt.show()
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(fluo / fluo.max(), color="red", lw=2, label="Fluorescence")
ax.plot(npq, linestyle="dashed", color="black", lw=2, label="NPQ")
ax.axvspan(0, 2 * 120, color=(0, 0, 0, 1 / 4))
ax.axvspan(12 * 120, 21 * 120, color=(0, 0, 0, 1 / 4))
ax.set(
ylim=(0, 1.1),
xlim=(0, 2500),
xlabel="Time/(s)",
ylabel="Fluorescence (normalised)",
)
ax.legend(loc="lower right")
ax.grid(visible=True)
plt.show()