mxlmodels 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,864 @@
1
+ """Matuszynska 2016 PhD photosynthesis model.
2
+
3
+ Full chloroplast electron transport chain with non-photochemical quenching (NPQ)
4
+ and LHC state transitions. Covers PSII/PSI, cytochrome b6f, FNR, ATP synthase,
5
+ the xanthophyll cycle (violaxanthin ↔ zeaxanthin), PsbS protonation, and
6
+ cyclic electron flow around PSI.
7
+
8
+ Reference: Matuszyńska, Anna Barbara.
9
+ Mathematical models of light acclimation mechanisms in higher plants and green algae.
10
+ Dissertation, Düsseldorf, Heinrich-Heine-Universität, 2016.
11
+ """
12
+
13
+ import math
14
+
15
+ import numpy as np
16
+ from mxlpy import Derived, Model
17
+ from mxlpy.surrogates import qss
18
+
19
+
20
+ def _moiety_1(
21
+ concentration: float,
22
+ total: float,
23
+ ) -> float:
24
+ """Conservation moiety: total - concentration."""
25
+ return total - concentration
26
+
27
+
28
+ def _mass_action_1s(
29
+ s1: float,
30
+ k_fwd: float,
31
+ ) -> float:
32
+ """Mass-action rate for one substrate."""
33
+ return k_fwd * s1
34
+
35
+
36
+ def _dg_ph(
37
+ r: float,
38
+ t: float,
39
+ ) -> float:
40
+ """Thermodynamic coefficient dG/dpH = RT*ln(10) in kJ/mol."""
41
+ return np.log(10) * r * t
42
+
43
+
44
+ def _ph_lumen(
45
+ protons: float,
46
+ ) -> float:
47
+ """Lumenal pH from proton concentration in mmol/mmol_Chl (conversion factor 0.00025)."""
48
+ return -np.log10(protons * 0.00025)
49
+
50
+
51
+ def _quencher(
52
+ psbs: float,
53
+ vx: float,
54
+ psbsp: float,
55
+ zx: float,
56
+ y0: float,
57
+ y1: float,
58
+ y2: float,
59
+ y3: float,
60
+ k_z_sat: float,
61
+ ) -> float:
62
+ """co-operative 4-state quenching mechanism.
63
+
64
+ gamma0: slow quenching of (Vx - protonation)
65
+ gamma1: fast quenching (Vx + protonation)
66
+ gamma2: fastest possible quenching (Zx + protonation)
67
+ gamma3: slow quenching of Zx present (Zx - protonation).
68
+ """
69
+ ZAnt = zx / (zx + k_z_sat)
70
+ return y0 * vx * psbs + y1 * vx * psbsp + y2 * ZAnt * psbsp + y3 * ZAnt * psbs
71
+
72
+
73
+ def _keq_pq_red(
74
+ e0_qa: float,
75
+ f: float,
76
+ e0_pq: float,
77
+ p_hstroma: float,
78
+ d_g_p_h: float,
79
+ rt: float,
80
+ ) -> float:
81
+ """Equilibrium constant for PQ reduction by QA, pH-corrected via stroma proton contribution."""
82
+ dg1 = -e0_qa * f
83
+ dg2 = -2 * e0_pq * f
84
+ dg = -2 * dg1 + dg2 + 2 * p_hstroma * d_g_p_h
85
+ return np.exp(-dg / rt)
86
+
87
+
88
+ def _ps2_crosssection(
89
+ lhc: float,
90
+ static_ant_ii: float,
91
+ static_ant_i: float,
92
+ ) -> float:
93
+ """Equilibrium constant for PQ reduction by QA, pH-corrected via stroma proton contribution."""
94
+ return static_ant_ii + (1 - static_ant_ii - static_ant_i) * lhc
95
+
96
+
97
+ def _keq_atp(
98
+ p_h: float,
99
+ delta_g0_atp: float,
100
+ d_g_p_h: float,
101
+ hpr: float,
102
+ p_hstroma: float,
103
+ pi_mol: float,
104
+ rt: float,
105
+ ) -> float:
106
+ """Equilibrium constant for ATP synthase, driven by the transmembrane proton gradient."""
107
+ delta_g = delta_g0_atp - d_g_p_h * hpr * (p_hstroma - p_h)
108
+ return pi_mol * math.exp(-delta_g / rt)
109
+
110
+
111
+ def _keq_cytb6f(
112
+ p_h: float,
113
+ f: float,
114
+ e0_pq: float,
115
+ e0_pc: float,
116
+ p_hstroma: float,
117
+ rt: float,
118
+ d_g_p_h: float,
119
+ ) -> float:
120
+ """Equilibrium constant of cytochrome b6f from redox potentials and transmembrane pH gradient."""
121
+ DG1 = -2 * f * e0_pq
122
+ DG2 = -f * e0_pc
123
+ DG = -(DG1 + 2 * d_g_p_h * p_h) + 2 * DG2 + 2 * d_g_p_h * (p_hstroma - p_h)
124
+ return math.exp(-DG / rt)
125
+
126
+
127
+ def _keq_fnr(
128
+ e0_fd: float,
129
+ f: float,
130
+ e0_nadp: float,
131
+ p_hstroma: float,
132
+ d_g_p_h: float,
133
+ rt: float,
134
+ ) -> float:
135
+ """Equilibrium constant for FNR: Fd-mediated NADP+ reduction, pH-corrected."""
136
+ dg1 = -e0_fd * f
137
+ dg2 = -2 * e0_nadp * f
138
+ dg = -2 * dg1 + dg2 + d_g_p_h * p_hstroma
139
+ return math.exp(-dg / rt)
140
+
141
+
142
+ def _keq_pcp700(
143
+ e0_pc: float,
144
+ f: float,
145
+ eo_p700: float,
146
+ rt: float,
147
+ ) -> float:
148
+ """Equilibrium constant for PC -> P700 electron transfer from standard redox potentials."""
149
+ dg1 = -e0_pc * f
150
+ dg2 = -eo_p700 * f
151
+ dg = -dg1 + dg2
152
+ return math.exp(-dg / rt)
153
+
154
+
155
+ def _keq_faf_d(
156
+ e0_fa: float,
157
+ f: float,
158
+ e0_fd: float,
159
+ rt: float,
160
+ ) -> float:
161
+ """Equilibrium constant for FA -> Fd electron transfer from standard redox potentials."""
162
+ dg1 = -e0_fa * f
163
+ dg2 = -e0_fd * f
164
+ dg = -dg1 + dg2
165
+ return math.exp(-dg / rt)
166
+
167
+
168
+ def _ps1states_2019(
169
+ pc_px: float,
170
+ pc_red: float,
171
+ fd_ox: float,
172
+ fd_red: float,
173
+ ps2cs: float,
174
+ psi_tot: float,
175
+ k_fd_red: float,
176
+ keq_fafd: float,
177
+ keq_pcp700: float,
178
+ k_pc_ox: float,
179
+ pfd: float,
180
+ ) -> float:
181
+ """QSSA calculates open state of PSI.
182
+
183
+ depends on reduction states of plastocyanin and ferredoxin
184
+ C = [PC], F = [Fd] (ox. forms).
185
+ """
186
+ L = (1 - ps2cs) * pfd
187
+ return psi_tot / (
188
+ 1
189
+ + L / (k_fd_red * fd_ox)
190
+ + (1 + fd_red / (keq_fafd * fd_ox))
191
+ * (pc_px / (keq_pcp700 * pc_red) + L / (k_pc_ox * pc_red))
192
+ )
193
+
194
+
195
+ def _rate_atp_synthase_2016(
196
+ atp: float,
197
+ adp: float,
198
+ keq_at_psynthase: float,
199
+ k_at_psynth: float,
200
+ ) -> float:
201
+ """ATP synthase rate (2016 formulation): linear reversible kinetics driven by Keq."""
202
+ return k_at_psynth * (adp - atp / keq_at_psynthase)
203
+
204
+
205
+ def _neg_div(
206
+ x: float,
207
+ y: float,
208
+ ) -> float:
209
+ """Return -x / y."""
210
+ return -x / y
211
+
212
+
213
+ def _b6f(
214
+ pc_ox: float,
215
+ pq_ox: float,
216
+ pq_red: float,
217
+ pc_red: float,
218
+ keq_b6f: float,
219
+ k_cytb6f: float,
220
+ ) -> float:
221
+ """Cytochrome b6f rate: reversible mass action clamped to -kCytb6f to avoid runaway reverse flux."""
222
+ return max(
223
+ k_cytb6f * (pq_red * pc_ox**2 - pq_ox * pc_red**2 / keq_b6f),
224
+ -k_cytb6f,
225
+ )
226
+
227
+
228
+ def _four_div_by(
229
+ x: float,
230
+ ) -> float:
231
+ """Return 4/x; used for the 4-proton stoichiometry of b6f scaled by buffering capacity."""
232
+ return 4.0 / x
233
+
234
+
235
+ def _protons_stroma_2016(
236
+ ph: float,
237
+ ) -> float:
238
+ """Convert stromal pH to proton concentration (µmol/L).
239
+
240
+ Introduced by the Matuszynska 2016 PhD model.
241
+ """
242
+ return 4000.0 * 10 ** (-ph)
243
+
244
+
245
+ def _protonation_hill(
246
+ vx: float,
247
+ h: float,
248
+ nh: float,
249
+ k_fwd: float,
250
+ k_ph_sat: float,
251
+ ) -> float:
252
+ """Hill-type protonation rate scaled by lumenal proton concentration."""
253
+ return k_fwd * (h**nh / (h**nh + _protons_stroma_2016(k_ph_sat) ** nh)) * vx # type: ignore
254
+
255
+
256
+ def _rate_cyclic_electron_flow(
257
+ pox: float,
258
+ fdred: float,
259
+ kcyc: float,
260
+ ) -> float:
261
+ """Cyclic electron flow rate: mass action on Fd_red^2 and PQ_ox."""
262
+ return kcyc * fdred**2 * pox
263
+
264
+
265
+ def _rate_protonation_hill(
266
+ vx: float,
267
+ h: float,
268
+ k_fwd: float,
269
+ n_h: float,
270
+ kph_sat: float,
271
+ ) -> float:
272
+ """Hill-type deepoxidase rate activated by lumenal proton concentration."""
273
+ return k_fwd * (h**n_h / (h**n_h + _protons_stroma_2016(kph_sat) ** n_h)) * vx # type: ignore
274
+
275
+
276
+ def _rate_fnr2016(
277
+ fd_ox: float,
278
+ fd_red: float,
279
+ nadph: float,
280
+ nadp: float,
281
+ vmax: float,
282
+ km_fd_red: float,
283
+ km_nadph: float,
284
+ keq: float,
285
+ ) -> float:
286
+ """FNR rate (2016 formulation): reversible ping-pong with Fd^2 stoichiometry, mmol/mmol_Chl units."""
287
+ fdred = fd_red / km_fd_red
288
+ fdox = fd_ox / km_fd_red
289
+ nadph = nadph / km_nadph
290
+ nadp = nadp / km_nadph
291
+ return (
292
+ vmax
293
+ * (fdred**2 * nadp - fdox**2 * nadph / keq)
294
+ / ((1 + fdred + fdred**2) * (1 + nadp) + (1 + fdox + fdox**2) * (1 + nadph) - 1)
295
+ )
296
+
297
+
298
+ def _rate_ps2(
299
+ b1: float,
300
+ k2: float,
301
+ ) -> float:
302
+ """PSII electron transfer rate from the open-excited state B1 and photochemistry rate constant k2."""
303
+ return 0.5 * k2 * b1
304
+
305
+
306
+ def _two_div_by(
307
+ x: float,
308
+ ) -> float:
309
+ """Return 2/x; used for the 2-proton stoichiometry of PSII scaled by buffering capacity."""
310
+ return 2.0 / x
311
+
312
+
313
+ def _rate_ps1(
314
+ a: float,
315
+ ps2cs: float,
316
+ pfd: float,
317
+ ) -> float:
318
+ """PSI electron transfer rate: open PSI centers (a) * light absorbed by PSI antenna."""
319
+ return (1 - ps2cs) * pfd * a
320
+
321
+
322
+ def _rate_leak(
323
+ protons_lumen: float,
324
+ ph_stroma: float,
325
+ k_leak: float,
326
+ ) -> float:
327
+ """Passive proton leak across the thylakoid membrane, proportional to the proton gradient."""
328
+ return k_leak * (protons_lumen - _protons_stroma_2016(ph_stroma))
329
+
330
+
331
+ def _neg_one_div_by(
332
+ x: float,
333
+ ) -> float:
334
+ """Return -1/x; used for negated unit stoichiometry scaled by buffering capacity."""
335
+ return -1.0 / x
336
+
337
+
338
+ def _mass_action_2s(
339
+ s1: float,
340
+ s2: float,
341
+ k_fwd: float,
342
+ ) -> float:
343
+ """Mass-action rate for two substrates."""
344
+ return k_fwd * s1 * s2
345
+
346
+
347
+ def _rate_state_transition_ps1_ps2(
348
+ ant: float,
349
+ pox: float,
350
+ p_tot: float,
351
+ k_stt7: float,
352
+ km_st: float,
353
+ n_st: float,
354
+ ) -> float:
355
+ """STT7-kinase phosphorylation of LHC; inhibited by oxidised PQ (state 1 → 2 transition)."""
356
+ return k_stt7 * (1 / (1 + (pox / p_tot / km_st) ** n_st)) * ant
357
+
358
+
359
+ def _ps2states_2016_phd_surrogate(
360
+ pq_ox: float,
361
+ pq_red: float,
362
+ ps2cs: float,
363
+ quencher: float,
364
+ psii_tot: float,
365
+ k2: float,
366
+ k_f: float,
367
+ _kh: float,
368
+ keq_pq_red: float,
369
+ k_pq_red: float,
370
+ pfd: float,
371
+ k_h0: float,
372
+ ) -> tuple[float, float, float, float]:
373
+ """PSII state populations (PHD quenching model, 2016) via analytical closed-form surrogate."""
374
+ x0 = k_f**2
375
+ x1 = k_h0**2
376
+ x2 = k2 * k_f
377
+ x3 = k2 * k_h0
378
+ x4 = 2 * k_f
379
+ x5 = k_h0 * x4
380
+ x6 = _kh * quencher
381
+ x7 = k2 * x6
382
+ x8 = x4 * x6
383
+ x9 = 2 * x6
384
+ x10 = k_h0 * x9
385
+ x11 = _kh**2 * quencher**2
386
+ x12 = k2 * keq_pq_red
387
+ x13 = k_pq_red * keq_pq_red * pq_ox
388
+ x14 = k_pq_red * pq_red
389
+ x15 = k2 * x14
390
+ x16 = pfd * ps2cs
391
+ x17 = k_f * x14
392
+ x18 = k_h0 * x14
393
+ x19 = x14 * x6
394
+ x20 = x13 * x16
395
+ x21 = keq_pq_red * x16
396
+ x22 = (
397
+ x0 * x14
398
+ + x1 * x14
399
+ + x11 * x14
400
+ + x14 * x2
401
+ + x14 * x3
402
+ + x14 * x5
403
+ + x14 * x7
404
+ + x14 * x8
405
+ + x18 * x9
406
+ + x2 * x21
407
+ + x21 * x3
408
+ + x21 * x7
409
+ )
410
+ x23 = psii_tot / (
411
+ k_f * x20
412
+ + k_h0 * x20
413
+ + pfd**2 * ps2cs**2 * x12
414
+ + x0 * x13
415
+ + x1 * x13
416
+ + x10 * x13
417
+ + x11 * x13
418
+ + x13 * x2
419
+ + x13 * x3
420
+ + x13 * x5
421
+ + x13 * x7
422
+ + x13 * x8
423
+ + x15 * x16
424
+ + x16 * x17
425
+ + x16 * x18
426
+ + x16 * x19
427
+ + x20 * x6
428
+ + x22
429
+ )
430
+ x24 = x16 * x23
431
+ _B0 = x13 * x23 * (x0 + x1 + x10 + x11 + x2 + x3 + x5 + x7 + x8)
432
+ _B1 = x13 * x24 * (k_f + k_h0 + x6)
433
+ _B2 = x22 * x23
434
+ _B3 = x24 * (x12 * x16 + x15 + x17 + x18 + x19)
435
+ return _B0, _B1, _B2, _B3
436
+
437
+
438
+ def _div(
439
+ x: float,
440
+ y: float,
441
+ ) -> float:
442
+ """Return x / y."""
443
+ return x / y
444
+
445
+
446
+ def _rate_fluorescence(
447
+ q: float,
448
+ b0: float,
449
+ b2: float,
450
+ ps2cs: float,
451
+ k2: float,
452
+ k_f: float,
453
+ k_h: float,
454
+ ) -> float:
455
+ """Chlorophyll fluorescence yield from open (B0) and closed (B2) PSII centres."""
456
+ return ps2cs * k_f * b0 / (k_f + k2 + k_h * q) + ps2cs * k_f * b2 / (k_f + k_h * q)
457
+
458
+
459
+ def create_model() -> Model:
460
+ """Matuszynska 2016 PhD photosynthesis model.
461
+
462
+ Full chloroplast electron transport chain with non-photochemical quenching (NPQ)
463
+ and LHC state transitions. Covers PSII/PSI, cytochrome b6f, FNR, ATP synthase,
464
+ the xanthophyll cycle (violaxanthin ↔ zeaxanthin), PsbS protonation, and
465
+ cyclic electron flow around PSI.
466
+
467
+ Reference: Matuszyńska, Anna Barbara.
468
+ Mathematical models of light acclimation mechanisms in higher plants and green algae.
469
+ Dissertation, Düsseldorf, Heinrich-Heine-Universität, 2016.
470
+ """
471
+ m: Model = Model()
472
+ m = m.add_variable("ATP", initial_value=1.6999999999999997)
473
+ m = m.add_variable("Plastoquinone (oxidised)", initial_value=4.706348349506148)
474
+ m = m.add_variable("Plastocyanine (oxidised)", initial_value=3.9414515288091567)
475
+ m = m.add_variable("Ferredoxine (oxidised)", initial_value=3.7761613271207324)
476
+ m = m.add_variable("protons_lumen", initial_value=7.737821100836988)
477
+ m = m.add_variable("Light-harvesting complex", initial_value=0.5105293511676007)
478
+ m = m.add_variable("PsbS (de-protonated)", initial_value=0.5000000001374878)
479
+ m = m.add_variable("Violaxanthin", initial_value=0.09090909090907397)
480
+ m = m.add_parameter("pH", value=7.9)
481
+ m = m.add_parameter("PPFD", value=100.0)
482
+ m = m.add_parameter("NADPH", value=0.6)
483
+ m = m.add_parameter("O2 (dissolved)_lumen", value=8.0)
484
+ m = m.add_parameter("bH", value=100.0)
485
+ m = m.add_parameter("F", value=96.485)
486
+ m = m.add_parameter("E^0_PC", value=0.38)
487
+ m = m.add_parameter("E^0_P700", value=0.48)
488
+ m = m.add_parameter("E^0_FA", value=-0.55)
489
+ m = m.add_parameter("E^0_Fd", value=-0.43)
490
+ m = m.add_parameter("E^0_NADP", value=-0.113)
491
+ m = m.add_parameter("NADP*", value=0.8)
492
+ m = m.add_parameter("R", value=0.0083)
493
+ m = m.add_parameter("T", value=298.0)
494
+ m = m.add_parameter("A*P", value=2.55)
495
+ m = m.add_parameter("Carotenoids_tot", value=1.0)
496
+ m = m.add_parameter("Fd*", value=5.0)
497
+ m = m.add_parameter("PC_tot", value=4.0)
498
+ m = m.add_parameter("PSBS_tot", value=1.0)
499
+ m = m.add_parameter("LHC_tot", value=1.0)
500
+ m = m.add_parameter("gamma0", value=0.1)
501
+ m = m.add_parameter("gamma1", value=0.25)
502
+ m = m.add_parameter("gamma2", value=0.6)
503
+ m = m.add_parameter("gamma3", value=0.15)
504
+ m = m.add_parameter("kZSat", value=0.12)
505
+ m = m.add_parameter("E^0_QA", value=-0.14)
506
+ m = m.add_parameter("E^0_PQ", value=0.354)
507
+ m = m.add_parameter("PQ_tot", value=17.5)
508
+ m = m.add_parameter("staticAntII", value=0.1)
509
+ m = m.add_parameter("staticAntI", value=0.37)
510
+ m = m.add_parameter("kf_atp_synthase", value=20.0)
511
+ m = m.add_parameter("HPR", value=4.666666666666667)
512
+ m = m.add_parameter("Pi_mol", value=0.01)
513
+ m = m.add_parameter("DeltaG0_ATP", value=30.6)
514
+ m = m.add_parameter("kcat_b6f", value=2.5)
515
+ m = m.add_parameter("kh_lhc_protonation", value=3.0)
516
+ m = m.add_parameter("kf_lhc_protonation", value=0.0096)
517
+ m = m.add_parameter("ksat_lhc_protonation", value=5.8)
518
+ m = m.add_parameter("kf_lhc_deprotonation", value=0.0096)
519
+ m = m.add_parameter("kf_cyclic_electron_flow", value=1.0)
520
+ m = m.add_parameter("kf_violaxanthin_deepoxidase", value=0.0024)
521
+ m = m.add_parameter("kh_violaxanthin_deepoxidase", value=5.0)
522
+ m = m.add_parameter("ksat_violaxanthin_deepoxidase", value=5.8)
523
+ m = m.add_parameter("kf_zeaxanthin_epoxidase", value=0.00024)
524
+ m = m.add_parameter("E0_fnr", value=3.0)
525
+ m = m.add_parameter("kcat_fnr", value=500.0)
526
+ m = m.add_parameter("km_fnr_Ferredoxine (reduced)", value=1.56)
527
+ m = m.add_parameter("km_fnr_NADP", value=0.22)
528
+ m = m.add_parameter("kf_ndh", value=0.002)
529
+ m = m.add_parameter("PSII_total", value=2.5)
530
+ m = m.add_parameter("PSI_total", value=2.5)
531
+ m = m.add_parameter("kH0", value=500000000.0)
532
+ m = m.add_parameter("kPQred", value=250.0)
533
+ m = m.add_parameter("kPCox", value=2500.0)
534
+ m = m.add_parameter("kFdred", value=250000.0)
535
+ m = m.add_parameter("k2", value=5000000000.0)
536
+ m = m.add_parameter("kH", value=5000000000.0)
537
+ m = m.add_parameter("kF", value=625000000.0)
538
+ m = m.add_parameter("convf", value=0.032)
539
+ m = m.add_parameter("kf_proton_leak", value=10.0)
540
+ m = m.add_parameter("kPTOX", value=0.01)
541
+ m = m.add_parameter("kStt7", value=0.0035)
542
+ m = m.add_parameter("km_lhc_state_transition_12", value=0.2)
543
+ m = m.add_parameter("n_ST", value=2.0)
544
+ m = m.add_parameter("kPph1", value=0.0013)
545
+ m = m.add_parameter("kf_ex_atp", value=10.0)
546
+ m = m.add_derived(
547
+ "NADP",
548
+ fn=_moiety_1,
549
+ args=["NADPH", "NADP*"],
550
+ )
551
+ m = m.add_derived(
552
+ "RT",
553
+ fn=_mass_action_1s,
554
+ args=["R", "T"],
555
+ )
556
+ m = m.add_derived(
557
+ "ADP",
558
+ fn=_moiety_1,
559
+ args=["ATP", "A*P"],
560
+ )
561
+ m = m.add_derived(
562
+ "dG_pH",
563
+ fn=_dg_ph,
564
+ args=["R", "T"],
565
+ )
566
+ m = m.add_derived(
567
+ "pH_lumen",
568
+ fn=_ph_lumen,
569
+ args=["protons_lumen"],
570
+ )
571
+ m = m.add_derived(
572
+ "Zeaxanthin",
573
+ fn=_moiety_1,
574
+ args=["Violaxanthin", "Carotenoids_tot"],
575
+ )
576
+ m = m.add_derived(
577
+ "Ferredoxine (reduced)",
578
+ fn=_moiety_1,
579
+ args=["Ferredoxine (oxidised)", "Fd*"],
580
+ )
581
+ m = m.add_derived(
582
+ "Plastocyanine (reduced)",
583
+ fn=_moiety_1,
584
+ args=["Plastocyanine (oxidised)", "PC_tot"],
585
+ )
586
+ m = m.add_derived(
587
+ "PsbS (protonated)",
588
+ fn=_moiety_1,
589
+ args=["PsbS (de-protonated)", "PSBS_tot"],
590
+ )
591
+ m = m.add_derived(
592
+ "Light-harvesting complex (protonated)",
593
+ fn=_moiety_1,
594
+ args=["Light-harvesting complex", "LHC_tot"],
595
+ )
596
+ m = m.add_derived(
597
+ "Q",
598
+ fn=_quencher,
599
+ args=[
600
+ "PsbS (de-protonated)",
601
+ "Violaxanthin",
602
+ "PsbS (protonated)",
603
+ "Zeaxanthin",
604
+ "gamma0",
605
+ "gamma1",
606
+ "gamma2",
607
+ "gamma3",
608
+ "kZSat",
609
+ ],
610
+ )
611
+ m = m.add_derived(
612
+ "keq_Plastoquinone (reduced)",
613
+ fn=_keq_pq_red,
614
+ args=["E^0_QA", "F", "E^0_PQ", "pH", "dG_pH", "RT"],
615
+ )
616
+ m = m.add_derived(
617
+ "Plastoquinone (reduced)",
618
+ fn=_moiety_1,
619
+ args=["Plastoquinone (oxidised)", "PQ_tot"],
620
+ )
621
+ m = m.add_derived(
622
+ "PSII_cross_section",
623
+ fn=_ps2_crosssection,
624
+ args=["Light-harvesting complex", "staticAntII", "staticAntI"],
625
+ )
626
+ m = m.add_derived(
627
+ "keq_atp_synthase",
628
+ fn=_keq_atp,
629
+ args=["pH_lumen", "DeltaG0_ATP", "dG_pH", "HPR", "pH", "Pi_mol", "RT"],
630
+ )
631
+ m = m.add_derived(
632
+ "keq_b6f",
633
+ fn=_keq_cytb6f,
634
+ args=["pH_lumen", "F", "E^0_PQ", "E^0_PC", "pH", "RT", "dG_pH"],
635
+ )
636
+ m = m.add_derived(
637
+ "keq_fnr",
638
+ fn=_keq_fnr,
639
+ args=["E^0_Fd", "F", "E^0_NADP", "pH", "dG_pH", "RT"],
640
+ )
641
+ m = m.add_derived(
642
+ "vmax_fnr",
643
+ fn=_mass_action_1s,
644
+ args=["kcat_fnr", "E0_fnr"],
645
+ )
646
+ m = m.add_derived(
647
+ "keq_PCP700",
648
+ fn=_keq_pcp700,
649
+ args=["E^0_PC", "F", "E^0_P700", "RT"],
650
+ )
651
+ m = m.add_derived(
652
+ "keq_ferredoxin_reductase",
653
+ fn=_keq_faf_d,
654
+ args=["E^0_FA", "F", "E^0_Fd", "RT"],
655
+ )
656
+ m = m.add_derived(
657
+ "A1",
658
+ fn=_ps1states_2019,
659
+ args=[
660
+ "Plastocyanine (oxidised)",
661
+ "Plastocyanine (reduced)",
662
+ "Ferredoxine (oxidised)",
663
+ "Ferredoxine (reduced)",
664
+ "PSII_cross_section",
665
+ "PSI_total",
666
+ "kFdred",
667
+ "keq_ferredoxin_reductase",
668
+ "keq_PCP700",
669
+ "kPCox",
670
+ "PPFD",
671
+ ],
672
+ )
673
+ m = m.add_reaction(
674
+ "atp_synthase",
675
+ fn=_rate_atp_synthase_2016,
676
+ args=["ATP", "ADP", "keq_atp_synthase", "kf_atp_synthase"],
677
+ stoichiometry={
678
+ "ATP": 1.0,
679
+ "protons_lumen": Derived(fn=_neg_div, args=["HPR", "bH"]),
680
+ },
681
+ )
682
+ m = m.add_reaction(
683
+ "b6f",
684
+ fn=_b6f,
685
+ args=[
686
+ "Plastocyanine (oxidised)",
687
+ "Plastoquinone (oxidised)",
688
+ "Plastoquinone (reduced)",
689
+ "Plastocyanine (reduced)",
690
+ "keq_b6f",
691
+ "kcat_b6f",
692
+ ],
693
+ stoichiometry={
694
+ "Plastocyanine (oxidised)": -2,
695
+ "Plastoquinone (oxidised)": 1,
696
+ "protons_lumen": Derived(fn=_four_div_by, args=["bH"]),
697
+ },
698
+ )
699
+ m = m.add_reaction(
700
+ "lhc_protonation",
701
+ fn=_protonation_hill,
702
+ args=[
703
+ "PsbS (de-protonated)",
704
+ "protons_lumen",
705
+ "kh_lhc_protonation",
706
+ "kf_lhc_protonation",
707
+ "ksat_lhc_protonation",
708
+ ],
709
+ stoichiometry={"PsbS (de-protonated)": -1},
710
+ )
711
+ m = m.add_reaction(
712
+ "lhc_deprotonation",
713
+ fn=_mass_action_1s,
714
+ args=["PsbS (protonated)", "kf_lhc_deprotonation"],
715
+ stoichiometry={"PsbS (de-protonated)": 1},
716
+ )
717
+ m = m.add_reaction(
718
+ "cyclic_electron_flow",
719
+ fn=_rate_cyclic_electron_flow,
720
+ args=[
721
+ "Plastoquinone (oxidised)",
722
+ "Ferredoxine (reduced)",
723
+ "kf_cyclic_electron_flow",
724
+ ],
725
+ stoichiometry={"Plastoquinone (oxidised)": -1, "Ferredoxine (oxidised)": 2},
726
+ )
727
+ m = m.add_reaction(
728
+ "violaxanthin_deepoxidase",
729
+ fn=_rate_protonation_hill,
730
+ args=[
731
+ "Violaxanthin",
732
+ "protons_lumen",
733
+ "kf_violaxanthin_deepoxidase",
734
+ "kh_violaxanthin_deepoxidase",
735
+ "ksat_violaxanthin_deepoxidase",
736
+ ],
737
+ stoichiometry={"Violaxanthin": -1},
738
+ )
739
+ m = m.add_reaction(
740
+ "zeaxanthin_epoxidase",
741
+ fn=_mass_action_1s,
742
+ args=["Zeaxanthin", "kf_zeaxanthin_epoxidase"],
743
+ stoichiometry={"Violaxanthin": 1},
744
+ )
745
+ m = m.add_reaction(
746
+ "fnr",
747
+ fn=_rate_fnr2016,
748
+ args=[
749
+ "Ferredoxine (oxidised)",
750
+ "Ferredoxine (reduced)",
751
+ "NADPH",
752
+ "NADP",
753
+ "vmax_fnr",
754
+ "km_fnr_Ferredoxine (reduced)",
755
+ "km_fnr_NADP",
756
+ "keq_fnr",
757
+ ],
758
+ stoichiometry={"Ferredoxine (oxidised)": 2},
759
+ )
760
+ m = m.add_reaction(
761
+ "ndh",
762
+ fn=_mass_action_1s,
763
+ args=["Plastoquinone (oxidised)", "kf_ndh"],
764
+ stoichiometry={"Plastoquinone (oxidised)": -1},
765
+ )
766
+ m = m.add_reaction(
767
+ "PSII",
768
+ fn=_rate_ps2,
769
+ args=["B1", "k2"],
770
+ stoichiometry={
771
+ "Plastoquinone (oxidised)": -1,
772
+ "protons_lumen": Derived(fn=_two_div_by, args=["bH"]),
773
+ },
774
+ )
775
+ m = m.add_reaction(
776
+ "PSI",
777
+ fn=_rate_ps1,
778
+ args=["A1", "PSII_cross_section", "PPFD"],
779
+ stoichiometry={"Ferredoxine (oxidised)": -1, "Plastocyanine (oxidised)": 1},
780
+ )
781
+ m = m.add_reaction(
782
+ "proton_leak",
783
+ fn=_rate_leak,
784
+ args=["protons_lumen", "pH", "kf_proton_leak"],
785
+ stoichiometry={"protons_lumen": Derived(fn=_neg_one_div_by, args=["bH"])},
786
+ )
787
+ m = m.add_reaction(
788
+ "PTOX",
789
+ fn=_mass_action_2s,
790
+ args=["Plastoquinone (reduced)", "O2 (dissolved)_lumen", "kPTOX"],
791
+ stoichiometry={"Plastoquinone (oxidised)": 1},
792
+ )
793
+ m = m.add_reaction(
794
+ "lhc_state_transition_12",
795
+ fn=_rate_state_transition_ps1_ps2,
796
+ args=[
797
+ "Light-harvesting complex",
798
+ "Plastoquinone (oxidised)",
799
+ "PQ_tot",
800
+ "kStt7",
801
+ "km_lhc_state_transition_12",
802
+ "n_ST",
803
+ ],
804
+ stoichiometry={"Light-harvesting complex": -1},
805
+ )
806
+ m = m.add_reaction(
807
+ "lhc_state_transition_21",
808
+ fn=_mass_action_1s,
809
+ args=["Light-harvesting complex (protonated)", "kPph1"],
810
+ stoichiometry={"Light-harvesting complex": 1},
811
+ )
812
+ m = m.add_reaction(
813
+ "ex_atp",
814
+ fn=_mass_action_1s,
815
+ args=["ATP", "kf_ex_atp"],
816
+ stoichiometry={"ATP": -1},
817
+ )
818
+ m = m.add_surrogate(
819
+ "ps2states",
820
+ qss.Surrogate(
821
+ model=_ps2states_2016_phd_surrogate,
822
+ args=[
823
+ "Plastoquinone (oxidised)",
824
+ "Plastoquinone (reduced)",
825
+ "PSII_cross_section",
826
+ "Q",
827
+ "PSII_total",
828
+ "k2",
829
+ "kF",
830
+ "kH",
831
+ "keq_Plastoquinone (reduced)",
832
+ "kPQred",
833
+ "PPFD",
834
+ "kH0",
835
+ ],
836
+ outputs=["B0", "B1", "B2", "B3"],
837
+ ),
838
+ )
839
+ m = m.add_readout(
840
+ "PQ_ox/tot",
841
+ fn=_div,
842
+ args=["Plastoquinone (reduced)", "PQ_tot"],
843
+ )
844
+ m = m.add_readout(
845
+ "Fd_ox/tot",
846
+ fn=_div,
847
+ args=["Ferredoxine (reduced)", "Fd*"],
848
+ )
849
+ m = m.add_readout(
850
+ "PC_ox/tot",
851
+ fn=_div,
852
+ args=["Plastocyanine (reduced)", "PC_tot"],
853
+ )
854
+ m = m.add_readout(
855
+ "ATP/tot",
856
+ fn=_div,
857
+ args=["ATP", "A*P"],
858
+ )
859
+ m = m.add_readout(
860
+ "Fluo",
861
+ fn=_rate_fluorescence,
862
+ args=["Q", "B0", "B2", "PSII_cross_section", "k2", "kF", "kH"],
863
+ )
864
+ return m # noqa: RET504