Visualise response and Planck spectrum fits
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python
|
||||
"""Overlay one or more emission spectra, response-corrected, with Planck fits.
|
||||
|
||||
For each spectrum CSV: optionally response-correct it (--response/--dark plus
|
||||
--integration, as grab_spectrum.py --response would), fit a Planck curve over
|
||||
--band, and plot the corrected spectrum with its fit and the fitted temperature.
|
||||
Reuses the correction and the fit from the rest of the project.
|
||||
|
||||
Usage: python plot_emission.py f1.csv f2.csv ... [--response R.csv --dark D.csv
|
||||
--integration US] [--band LO HI] [--xlim LO HI]
|
||||
[--png fig.png]
|
||||
"""
|
||||
import argparse
|
||||
|
||||
import numpy as np
|
||||
import matplotlib
|
||||
matplotlib.use("Agg")
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from response import add_calibration_args, apply_response, dark_at, load_csv
|
||||
from fit_temperature import fit_planck
|
||||
|
||||
p = argparse.ArgumentParser(description=__doc__,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
p.add_argument("spectra", nargs="+", help="emission spectrum CSVs")
|
||||
p.add_argument("--integration", type=int, metavar="US",
|
||||
help="integration time (us) the spectra were captured at; required with --dark")
|
||||
p.add_argument("--band", nargs=2, type=float, default=[650.0, 850.0],
|
||||
metavar=("LO", "HI"), help="Planck fit band in nm (default: 650 850)")
|
||||
p.add_argument("--xlim", nargs=2, type=float, default=[560.0, 930.0],
|
||||
metavar=("LO", "HI"), help="plot x-range in nm (default: 560 930)")
|
||||
p.add_argument("--png", default="emission_fit.png")
|
||||
add_calibration_args(p)
|
||||
args = p.parse_args()
|
||||
|
||||
cal = load_csv(args.response) if args.response else None
|
||||
dark = None
|
||||
if args.dark:
|
||||
if args.integration is None:
|
||||
p.error("--integration US is required with --dark")
|
||||
dark = dark_at(args.dark, args.integration)
|
||||
|
||||
lo, hi = args.band
|
||||
fig, ax = plt.subplots(figsize=(9, 5))
|
||||
for f in args.spectra:
|
||||
wl, y = load_csv(f)
|
||||
if cal is not None:
|
||||
y = apply_response(wl, y, cal, dark)
|
||||
result = fit_planck(wl, y, (lo, hi))
|
||||
m = (wl >= args.xlim[0]) & (wl <= args.xlim[1])
|
||||
(base,) = ax.plot(wl[m], y[m], lw=0.5, alpha=0.35)
|
||||
if result is None:
|
||||
print(f"{f}: no fit in {lo:.0f}-{hi:.0f} nm")
|
||||
continue
|
||||
temperature, dT, predict = result
|
||||
ax.plot(wl[m], predict(wl[m]), lw=2.0, color=base.get_color(),
|
||||
label=f"{f}: T = {temperature:.0f} K")
|
||||
print(f"{f}: T = {temperature:.2f} +/- {dT:.2f} K")
|
||||
|
||||
ax.axvspan(lo, hi, color="0.85", alpha=0.5, lw=0, zorder=0)
|
||||
ax.set_xlabel("wavelength (nm)")
|
||||
ax.set_ylabel("relative irradiance (response-corrected)")
|
||||
ax.set_title(f"Emission with Planck fit over {lo:.0f}-{hi:.0f} nm (shaded)")
|
||||
ax.set_xlim(*args.xlim)
|
||||
ax.set_ylim(bottom=0)
|
||||
ax.grid(alpha=0.3)
|
||||
ax.legend(fontsize=9, loc="upper left")
|
||||
fig.tight_layout()
|
||||
fig.savefig(args.png, dpi=130)
|
||||
print(f"wrote {args.png}")
|
||||
Reference in New Issue
Block a user