Skip to content

Commit 3d75b35

Browse files
committed
fig optimize
1 parent e40512f commit 3d75b35

9 files changed

+162
-2
lines changed

scripts/fig_c1_alignment.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,18 @@ def run(config: Dict | None = None, which: str = "full") -> Dict[str, List[str]]
9696
ax.set_xlabel("alignment angle (rad)")
9797
ax.set_ylabel("PDF")
9898
ax.set_title("C1: alignment of $T_\\mu$ and $\\partial_\\mu\\epsilon$")
99+
# ---- 容差線 & 註記統計 ----
100+
ang_tol = float((config or {}).get("c1", {}).get("angle_tol", 1e-3))
101+
ax.axvline(ang_tol, ls="--", lw=1.0, color="C1", label=f"tol={ang_tol:g}")
102+
mean = float(np.mean(angles))
103+
p95 = float(np.percentile(angles, 95))
104+
ax.text(
105+
0.98, 0.92,
106+
f"mean={mean:.2e}\n95%={p95:.2e}",
107+
transform=ax.transAxes, ha="right", va="top", fontsize=9
108+
)
109+
if ang_tol is not None:
110+
ax.legend(frameon=False, fontsize=9)
99111
fig.tight_layout()
100112
pdf_path = paths["pdf"] / "fig2_c1_alignment.pdf"
101113
fig.savefig(pdf_path, bbox_inches="tight")

scripts/fig_c1_pure_trace.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,21 @@ def run(config: Dict | None = None, which: str = "full") -> Dict[str, List[str]]
112112
ax.set_yscale("log")
113113
ax.set_ylabel("magnitude (log)")
114114
ax.set_title("C1: torsion components")
115+
# ---- 註記數值比 ----
116+
eps = 1e-300
117+
txt_lines = []
118+
if axial > 0:
119+
txt_lines.append(f"trace/axial ≈ {trace/max(axial, eps):.2e}")
120+
else:
121+
txt_lines.append("axial ≈ 0")
122+
if tensor > 0:
123+
txt_lines.append(f"trace/tensor ≈ {trace/max(tensor, eps):.2e}")
124+
else:
125+
txt_lines.append("tensor ≈ 0")
126+
ax.text(
127+
0.98, 0.95, "\n".join(txt_lines),
128+
transform=ax.transAxes, ha="right", va="top", fontsize=9
129+
)
115130
fig.tight_layout()
116131
pdf_path = paths["pdf"] / "fig1_c1_pure_trace.pdf"
117132
fig.savefig(pdf_path, bbox_inches="tight")

scripts/fig_c2_coeff_compare.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,23 @@ def run(config: Dict | None = None, which: str = "full") -> Dict[str, List[str]]
9292
ax.set_ylabel(r"$\|\Delta\|$")
9393
ax.set_title("C2 residual (smoke)" if which == "smoke" else "C2 residual scan")
9494
ax.grid(True, ls=":", alpha=0.6)
95+
96+
# ---- 目標殘差水平線 + 達成標註 ----
97+
resid_goal = float((config or {}).get("equivalence", {}).get("resid_goal", 1e-10))
98+
ax.axhline(resid_goal, ls="--", lw=1.0, color="C1", label=f"goal={resid_goal:.1e}")
99+
try:
100+
# 找到第一個低於目標的 IBP 容差
101+
mask = resids <= resid_goal
102+
if np.any(mask):
103+
th_hit = thresholds[np.argmax(mask)]
104+
ax.axvline(th_hit, ls=":", lw=1.0, color="C2")
105+
ax.text(
106+
th_hit, resid_goal, f" hit @ {th_hit:.1e}",
107+
va="bottom", ha="left", fontsize=8, color="C2"
108+
)
109+
ax.legend(frameon=False, fontsize=9)
110+
except Exception:
111+
pass
95112

96113
pdf = paths["pdfdir"] / ("fig3_c2_coeff_compare.pdf" if which != "smoke" else "fig3_c2_coeff_compare_smoke.pdf")
97114
fig.tight_layout()

scripts/fig_c3_cT_heatmap.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,16 @@ def run(config: Dict | None = None, which: str = "full") -> Dict[str, List[str]]
148148
ax.set_title(r"C3: $|c_T-1|$ heatmap")
149149
cb = fig.colorbar(im, ax=ax)
150150
cb.set_label("|c_T-1|")
151+
# ---- 等高線:|c_T - 1| = tol ----
152+
ct_tol = float((config or {}).get("c3", {}).get("ct_tol", 1e-3))
153+
try:
154+
CS = ax.contour(
155+
X, Y, np.abs(cT - 1.0),
156+
levels=[ct_tol], colors="w", linewidths=1.2
157+
)
158+
ax.clabel(CS, fmt={ct_tol: f"tol={ct_tol:g}"}, inline=True, fontsize=8)
159+
except Exception:
160+
pass
151161

152162
# optional locking overlay(若使用者提供 locking_curve)
153163
try:

scripts/fig_c3_degeneracy.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import matplotlib.pyplot as plt
1111
import numpy as np
12+
from matplotlib.ticker import MaxNLocator
1213

1314
REQUIRE_REAL = bool(int(os.environ.get("PALPT_REQUIRE_REAL_APIS", "0")))
1415

@@ -78,6 +79,20 @@ def run(config: Dict | None = None, which: str = "full") -> Dict[str, List[str]]
7879
ax.set_title("DoF spectrum (smoke)" if which == "smoke" else "DoF spectrum")
7980
ax.grid(True, ls=":", alpha=0.5)
8081

82+
ax.xaxis.set_major_locator(MaxNLocator(integer=True))
83+
# ---- 有效非零的閾值與計數 ----
84+
deg_tol = float((config or {}).get("c3", {}).get("deg_tol", 1e-10))
85+
ax.axhline(deg_tol, ls="--", lw=1.0, color="C1", label=f"tol={deg_tol:.1e}")
86+
try:
87+
n_phys = int(np.sum(eigs > deg_tol))
88+
ax.text(
89+
0.98, 0.92, f"#phys ≈ {n_phys}",
90+
transform=ax.transAxes, ha="right", va="top", fontsize=9
91+
)
92+
ax.legend(frameon=False, fontsize=9)
93+
except Exception:
94+
pass
95+
8196
pdf = paths["pdfdir"] / ("fig6_c3_degeneracy.pdf" if which != "smoke" else "fig6_c3_degeneracy_smoke.pdf")
8297
fig.tight_layout()
8398
fig.savefig(pdf, dpi=200)

scripts/fig_c3_dispersion.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,22 @@ def run(config: Dict | None = None, which: str = "full") -> Dict[str, List[str]]
8989
ax.set_ylabel(r"$c_T(k)$")
9090
ax.set_title("Dispersion (smoke)" if which == "smoke" else "Dispersion")
9191
ax.grid(True, ls=":", alpha=0.6)
92+
#ax.legend()
93+
# ---- 容差帶 around 1 ----
94+
ct_tol = float((config or {}).get("c3", {}).get("ct_tol", 1e-3))
95+
ax.fill_between(k, 1.0-ct_tol, 1.0+ct_tol, alpha=0.12, label=f"±{ct_tol:g} band")
9296
ax.legend()
93-
97+
# ---- 註記最大偏差 ----
98+
try:
99+
d_locked = np.abs(cT_locked - 1.0)
100+
d_unlk = np.abs(cT_unlocked - 1.0)
101+
note = (f"max|Δ_locked|={np.max(d_locked):.2e}\n"
102+
f"max|Δ_unlocked|={np.max(d_unlk):.2e}")
103+
ax.text(0.98, 0.05, note, transform=ax.transAxes,
104+
ha="right", va="bottom", fontsize=9)
105+
except Exception:
106+
pass
107+
94108
pdf = paths["pdfdir"] / ("fig5_c3_dispersion.pdf" if which != "smoke" else "fig5_c3_dispersion_smoke.pdf")
95109
fig.tight_layout()
96110
fig.savefig(pdf, dpi=200)

scripts/fig_flux_ratio.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ def build_from_config(config: dict | None):
5353
# 交給庫函式做理論值
5454
out = flux_ratio_FRW(R, {"flux": {"sigma": sigma, "c": c}})
5555
# out 期望含有:out["R"], out["R_DBI_CM"]
56+
R = np.asarray(out["R"], dtype=float)
57+
Q = np.asarray(out["R_DBI_CM"], dtype=float)
58+
eps = np.finfo(float).eps
5659

5760
# --- CSV ---
5861
csv_path = os.path.join(DATA_DIR, CSV_NAME)
@@ -65,11 +68,34 @@ def build_from_config(config: dict | None):
6568
# --- PDF ---
6669
pdf_path = os.path.join(PDF_DIR, PDF_NAME)
6770
plt.figure(figsize=(4.8, 3.2), dpi=180)
68-
plt.plot(out["R"], out["R_DBI_CM"], lw=1.6, label=r"$\mathcal{R}_{X/Y}(R)$")
71+
#plt.plot(out["R"], out["R_DBI_CM"], lw=1.6, label=r"$\mathcal{R}_{X/Y}(R)$")
72+
plt.plot(R, Q, lw=1.6, label=r"$\mathcal{R}_{X/Y}(R)$")
6973
plt.axhline(1.0, ls="--", lw=1.0, label="unity")
7074
plt.xlabel(r"$R$")
7175
plt.ylabel(r"$\mathcal{R}_{X/Y}$")
7276
plt.title(r"Boundary flux ratio $\to 1$ with $R^{-\sigma}$ tail")
77+
#plt.legend(frameon=False)
78+
# ---- 擬合 R^{-sigma} 的收斂率 ----
79+
try:
80+
fit_Rmin = float(_cfg_get(config, ["flux", "fit", "Rmin"], R.min() + 0.5*(R.max()-R.min())))
81+
mask = (R >= fit_Rmin) & (np.abs(Q-1.0) > 1e-14)
82+
if np.any(mask):
83+
X = np.log(R[mask])
84+
Y = np.log(np.abs(Q[mask] - 1.0) + eps)
85+
m, b = np.polyfit(X, Y, 1) # Y ≈ m X + b
86+
sigma_hat = -m
87+
A_hat = np.exp(b)
88+
# 以尾端平均號誌的符號還原 ±
89+
sgn = np.sign(np.mean(Q[mask] - 1.0))
90+
Qfit = 1.0 + sgn * A_hat * (R**(-sigma_hat))
91+
plt.plot(R, Qfit, ls=":", lw=1.2, label=rf"fit: $1+A R^{{-\hat\sigma}}$, $\hat\sigma$≈{sigma_hat:.2f}")
92+
plt.text(
93+
0.02, 0.05, rf"fit window: $R\ge {fit_Rmin:g}$",
94+
transform=plt.gca().transAxes, fontsize=8
95+
)
96+
except Exception:
97+
pass
98+
7399
plt.legend(frameon=False)
74100
plt.tight_layout()
75101
plt.savefig(pdf_path)

scripts/fig_gw_waveform_overlay.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,40 @@ def run(config: Dict | None = None, which: str = "full") -> Dict[str, List[str]]
118118
ax.set_ylabel("h")
119119
ax.set_title("GW waveform overlay")
120120
ax.legend()
121+
122+
# ---- 指標:max|Δh|、RMSE、相位差(以主頻估) ----
123+
try:
124+
h1 = d["gr"].astype(float)
125+
h2 = d["model"].astype(float)
126+
tt = d["t"].astype(float)
127+
# 幅度差與 RMSE
128+
max_abs = float(np.max(np.abs(h2 - h1)))
129+
rmse = float(np.sqrt(np.mean((h2 - h1)**2)))
130+
# 估時間位移:互相關最大點
131+
s1 = h1 - np.mean(h1)
132+
s2 = h2 - np.mean(h2)
133+
corr = np.correlate(s1, s2, mode="full")
134+
lag = int(np.argmax(corr) - (len(s1) - 1))
135+
dt = float((tt[1] - tt[0]) * lag)
136+
# 主頻:用 FFT 取最大頻率
137+
n = len(h1)
138+
dt0 = float(tt[1]-tt[0])
139+
freq = np.fft.rfftfreq(n, d=dt0)
140+
amp = np.abs(np.fft.rfft(h1))
141+
if len(freq) > 1:
142+
ipeak = int(np.argmax(amp[1:]) + 1)
143+
f0 = float(freq[ipeak])
144+
else:
145+
f0 = 0.0
146+
phase = float(2*np.pi*f0*dt) if f0 > 0 else 0.0
147+
note = (f"max|Δh|={max_abs:.2e}\n"
148+
f"RMSE={rmse:.2e}\n"
149+
f"Δt≈{dt:.2e}, Δφ≈{phase:.2e} rad")
150+
ax.text(0.98, 0.05, note, transform=ax.transAxes,
151+
ha="right", va="bottom", fontsize=9)
152+
except Exception:
153+
pass
154+
121155
fig.tight_layout()
122156
pdf_path = paths["pdf"] / "fig7_gw_waveform_overlay.pdf"
123157
fig.savefig(pdf_path, bbox_inches="tight")

scripts/fig_nlo_offsets.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,23 @@ def _plot_pdf(out: dict) -> str:
8787
plt.loglog(kpos, ref, ls="--", lw=1.0, label=r"$\propto k^2$")
8888

8989
plt.ylabel(r"$|\delta c_T^2|$")
90+
# ---- 斜率擬合(log–log)與 Λ 估計 ----
91+
try:
92+
X = np.log(kpos)
93+
Y = np.log(ypos)
94+
m, b = np.polyfit(X, Y, 1) # Y ≈ m X + b
95+
# 從 δcT^2 = bcoef * k^2 / Λ^2 推回 Λ^2 的 robust 估計
96+
# 需要配置裡的 bcoef(名為 Ricci_deps_deps_eff)
97+
bcoef = float(_cfg_get(globals().get("CFG_CACHE", None), ["nlo", "coeffs", "Ricci_deps_deps_eff"], 0.0))
98+
if bcoef > 0:
99+
lam2_est = np.median(bcoef*(kpos**2)/ypos)
100+
lam_est = np.sqrt(lam2_est)
101+
txt = rf"slope≈{m:.2f}, $\hat\Lambda$≈{lam_est:.2e}"
102+
else:
103+
txt = rf"slope≈{m:.2f}"
104+
plt.text(0.03, 0.05, txt, transform=plt.gca().transAxes, fontsize=9)
105+
except Exception:
106+
pass
90107
else:
91108
# 全為 0 或只有 1 個正值:避免 log-scaling 警告,改線性 y 軸
92109
plt.plot(k, yabs, lw=1.6, label=r"$|\delta c_T^2(k)|\approx 0$")

0 commit comments

Comments
 (0)