SHOW:
|
|
- or go back to the newest paste.
1 | import numpy as np | |
2 | import matplotlib.pyplot as plt | |
3 | from matplotlib import cm | |
4 | from tqdm import tqdm | |
5 | import os | |
6 | from scipy.integrate import solve_ivp | |
7 | ||
8 | # Parameters | |
9 | SM = 0.0 | |
10 | - | INT = 5.0 |
10 | + | INT = 10.0 |
11 | PROD = -2.0 | |
12 | ||
13 | TS1_values = np.linspace(5, 30, 40) | |
14 | - | TS2_values = np.linspace(5, 40, 40) |
14 | + | TS2_values = np.linspace(5, 30, 40) |
15 | ||
16 | R = 8.314e-3 | |
17 | T = 298.0 | |
18 | RT = R * T | |
19 | A = 1.0 | |
20 | ||
21 | # ODE system | |
22 | def reaction_odes(t, y, k1f, k1r, k2f, k2r): | |
23 | SM_conc, INT_conc, PROD_conc = y | |
24 | dSMdt = -k1f * SM_conc + k1r * INT_conc | |
25 | dINTdt = k1f * SM_conc - k1r * INT_conc - k2f * INT_conc + k2r * PROD_conc | |
26 | dPRODdt = k2f * INT_conc - k2r * PROD_conc | |
27 | return [dSMdt, dINTdt, dPRODdt] | |
28 | ||
29 | y0 = [1.0, 0.0, 0.0] | |
30 | t_span = (0, 1000.0) | |
31 | t_eval = [1000.0] | |
32 | ||
33 | TS1_grid, TS2_grid = np.meshgrid(TS1_values, TS2_values) | |
34 | rate_grid = np.zeros_like(TS1_grid) | |
35 | ||
36 | # Calculate rates | |
37 | for i in tqdm(range(len(TS2_values)), desc="Rows"): | |
38 | for j in range(len(TS1_values)): | |
39 | TS1_val = TS1_grid[i, j] | |
40 | TS2_val = TS2_grid[i, j] | |
41 | ||
42 | - | if (TS1_val >= 5) and (TS2_val >= 5) and ((TS2_val - INT) < (TS1_val - SM)): |
42 | + | if (TS1_val >= 10) and (TS2_val >= 10) and ((TS1_val - SM) > (TS2_val - INT)) and (TS2_val > TS1_val): |
43 | k1f = A * np.exp(-(TS1_val - SM) / RT) | |
44 | k1r = A * np.exp(-(TS1_val - INT) / RT) | |
45 | k2f = A * np.exp(-(TS2_val - INT) / RT) | |
46 | k2r = A * np.exp(-(TS2_val - PROD) / RT) | |
47 | ||
48 | sol = solve_ivp(reaction_odes, t_span, y0, t_eval=t_eval, args=(k1f, k1r, k2f, k2r)) | |
49 | if sol.success: | |
50 | SM_final, INT_final, PROD_final = sol.y[:, -1] | |
51 | rate = (k2f * INT_final) - (k2r * PROD_final) | |
52 | else: | |
53 | rate = np.nan | |
54 | else: | |
55 | rate = np.nan | |
56 | ||
57 | rate_grid[i, j] = rate | |
58 | ||
59 | # Stats | |
60 | valid_rates = rate_grid[~np.isnan(rate_grid)] | |
61 | mean_rate = np.mean(valid_rates) if valid_rates.size > 0 else np.nan | |
62 | std_rate = np.std(valid_rates) if valid_rates.size > 0 else np.nan | |
63 | max_rate = np.nanmax(rate_grid) | |
64 | min_rate = np.nanmin(rate_grid) | |
65 | ||
66 | print("Summary Statistics:") | |
67 | print(f"Mean rate: {mean_rate:.4e}") | |
68 | print(f"Std dev of rate: {std_rate:.4e}") | |
69 | print(f"Max rate: {max_rate:.4e}") | |
70 | print(f"Min rate: {min_rate:.4e}") | |
71 | ||
72 | # Calculate intersection line where TS1 = TS2 | |
73 | intersection_mask = np.isclose(TS1_grid, TS2_grid) | |
74 | intersection_TS1 = TS1_grid[intersection_mask] | |
75 | intersection_TS2 = TS2_grid[intersection_mask] | |
76 | intersection_rates = rate_grid[intersection_mask] | |
77 | ||
78 | # Plot | |
79 | fig = plt.figure(figsize=(10, 7)) | |
80 | ax = fig.add_subplot(111, projection='3d') | |
81 | ||
82 | masked_rate = np.ma.masked_invalid(rate_grid) | |
83 | ||
84 | # Plot the main surface | |
85 | surf = ax.plot_surface(TS1_grid, TS2_grid, masked_rate, cmap=cm.viridis, edgecolor='none') | |
86 | ||
87 | # Add color bar | |
88 | fig.colorbar(surf, shrink=0.5, aspect=5) | |
89 | ||
90 | # Labels and title | |
91 | - | output_path = "3d_rate_plot_odes_reversible.png" |
91 | + | ax.set_zlim(0, max_rate) |
92 | ax.set_xlabel('TS1 Free Energy') | |
93 | ax.set_ylabel('TS2 Free Energy') | |
94 | ax.set_zlabel('Net Rate') | |
95 | ax.set_title('Rate Dependence (Assuming A=1)') | |
96 | ||
97 | # Add legend | |
98 | ax.legend() | |
99 | ||
100 | # Invert axes | |
101 | ax.invert_xaxis() | |
102 | ax.invert_yaxis() | |
103 | ||
104 | # Set view angle | |
105 | ax.view_init(elev=30, azim=210) | |
106 | ||
107 | plt.tight_layout() | |
108 | ||
109 | # Save and show plot | |
110 | output_path = "3d_rate_plot_odes_intersection_line.png" | |
111 | plt.savefig(output_path, dpi=300) | |
112 | print(f"Plot saved as {os.path.abspath(output_path)}") | |
113 | ||
114 | plt.show() | |
115 |