Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions smoke_test/assets/sources/smoke_source_binary_catalog.dat
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
R062 Z087 Y106 J129 W146 H158 F184 K213 2MASS_Ks 2MASS_J 2MASS_H Bessell_U Bessell_B Bessell_V Bessell_I Bessell_R Kepler_Kp TESS DECam_z DECam_u DECam_g DECam_r DECam_i DECam_Y Gaia_G_EDR3 Gaia_BP_EDR3 Gaia_RP_EDR3 VISTA_Z VISTA_Y VISTA_J VISTA_H VISTA_Ks mul mub Vr U V W iMass CL age Teff logg pop Mass Mbol Radius [Fe/H] l b RA2000.0 DEC2000.0 Dist x y z A_Ks [alpha/Fe] ID Is_Binary primary_ID combined_logP
2.5212534e+01 2.3437151e+01 2.2946926e+01 2.2698885e+01 2.2737316e+01 2.2564209e+01 2.2718139e+01 2.2750813e+01 2.0916308e+01 2.1813254e+01 2.1137727e+01 2.8960719e+01 2.7692111e+01 2.6146455e+01 2.3327938e+01 2.4879330e+01 2.4833463e+01 2.3528349e+01 2.3269717e+01 2.8460170e+01 2.6830101e+01 2.5344168e+01 2.3886079e+01 2.3095472e+01 2.4810155e+01 2.6388821e+01 2.3603958e+01 2.2911913e+01 2.2447639e+01 2.1762028e+01 2.1155567e+01 2.0943504e+01 -1.0430274e+01 2.9710474e+00 5.3098679e+01 6.6088945e+01 1.0138185e+02 4.8754663e+01 1.3530942e-01 0.0000000e+00 1.0000000e+01 3.1466277e+03 5.1644453e+00 0.0000000e+00 1.3530814e-01 1.1389806e+01 1.5813397e-01 -9.4970712e-02 3.2006745e-03 4.2958514e-03 2.6640150e+02 -2.8931190e+01 2.9168337e+00 -5.2611722e+00 1.6294106e-04 1.1155346e-02 0.0000000e+00 0 1 1 1 1.0
1.8280023e+01 1.8068850e+01 1.8049266e+01 1.8055254e+01 1.8117239e+01 1.8116642e+01 1.8302014e+01 1.8562267e+01 1.6727762e+01 1.7164161e+01 1.6776748e+01 1.9448572e+01 1.9185598e+01 1.8437426e+01 1.7656769e+01 1.8021182e+01 1.8199912e+01 1.7754535e+01 1.8063731e+01 2.0042738e+01 1.8749093e+01 1.8215518e+01 1.8096851e+01 1.8045478e+01 1.8284698e+01 1.8650127e+01 1.7755000e+01 1.7576242e+01 1.7436794e+01 1.7135492e+01 1.6781831e+01 1.6731542e+01 5.4187211e-02 3.8186918e+00 -1.1389063e+02 -1.0081186e+02 2.4678124e+02 9.1264341e+01 9.0224882e-01 0.0000000e+00 1.0000000e+01 5.4611661e+03 4.4174184e+00 0.0000000e+00 9.0202770e-01 5.0507352e+00 9.7265615e-01 6.4701074e-02 3.5999997e+02 -3.7644077e-03 2.6640744e+02 -2.8938149e+01 4.5983030e+00 -3.5797075e+00 -2.6445424e-06 7.1391942e-03 0.0000000e+00 0 2 2 1 1.0
2.7189580e+01 2.4975054e+01 2.4260565e+01 2.3968756e+01 2.4030988e+01 2.3845912e+01 2.4039567e+01 2.3989889e+01 2.2155384e+01 2.3048865e+01 2.2390443e+01 3.1118061e+01 3.0030954e+01 2.8490833e+01 2.5036992e+01 2.6885617e+01 2.6681963e+01 2.5118838e+01 2.4731204e+01 3.0059395e+01 2.9036582e+01 2.7540074e+01 2.5635858e+01 2.4463607e+01 2.6583638e+01 2.8723106e+01 2.5259802e+01 2.4469663e+01 2.3817850e+01 2.2989283e+01 2.2414511e+01 2.2190391e+01 -6.5516244e+00 1.1716060e+00 -7.9343188e+01 -6.6373337e+01 9.2833791e+01 3.5265923e+01 1.4345340e-01 0.0000000e+00 1.0000000e+01 2.9315876e+03 5.1305404e+00 0.0000000e+00 1.4345205e-01 1.1600987e+01 1.6530046e-01 1.6760650e-01 4.3851388e-03 -2.5059108e-03 2.6640884e+02 -2.8933722e+01 4.9185785e+00 -3.2594326e+00 3.7644395e-04 6.5604172e-03 0.0000000e+00 0 3 0 0 0.0
2.6432685e+01 2.4491108e+01 2.3915671e+01 2.3656481e+01 2.3706363e+01 2.3533906e+01 2.3701900e+01 2.3710237e+01 2.1875732e+01 2.2758205e+01 2.2099233e+01 3.0094746e+01 2.8982746e+01 2.7485130e+01 2.4443064e+01 2.6113111e+01 2.6006401e+01 2.4604554e+01 2.4293562e+01 2.9474944e+01 2.8101540e+01 2.6642829e+01 2.5017614e+01 2.4081378e+01 2.5955676e+01 2.7725745e+01 2.4703953e+01 2.3972942e+01 2.3432310e+01 2.2704340e+01 2.2119082e+01 2.1905447e+01 -7.7780939e+00 -2.3327942e-01 -2.3962213e+01 -1.1064623e+01 6.4507357e+01 2.3963224e+00 1.5178442e-01 0.0000000e+00 1.0000000e+01 3.0756073e+03 5.1140763e+00 0.0000000e+00 1.5178288e-01 1.1246362e+01 1.7682473e-01 8.4404856e-02 2.6359830e-03 5.2891509e-03 2.6640020e+02 -2.8931154e+01 4.9113800e+00 -3.2666297e+00 2.2595581e-04 7.2438851e-03 0.0000000e+00 0 4 0 0 0.0
4.7021105e+01 3.4017351e+01 2.8549183e+01 2.4842273e+01 2.4605516e+01 2.2513490e+01 2.1428106e+01 2.0791151e+01 1.8956646e+01 2.4518952e+01 2.0729039e+01 7.5145964e+01 6.6431818e+01 5.2662162e+01 3.7022015e+01 4.5436628e+01 4.8035999e+01 4.0072213e+01 3.2192061e+01 7.2625737e+01 6.1205873e+01 4.5835721e+01 3.8642084e+01 2.9947132e+01 4.4114127e+01 5.4168672e+01 3.7180335e+01 3.2877854e+01 2.8552558e+01 2.4147819e+01 2.0674371e+01 1.8947702e+01 -4.6698104e+00 -2.4039011e+00 -1.4320101e+02 -1.3046019e+02 1.3330771e+02 -4.9805759e+01 8.1309438e-01 0.0000000e+00 1.0000000e+01 6.0603449e+03 4.3935837e+00 0.0000000e+00 8.1280571e-01 4.6548136e+00 9.4780662e-01 -7.9940091e-01 3.5997144e+02 1.6664060e-02 2.6637053e+02 -2.8951850e+01 5.0758087e+00 -3.1022000e+00 -2.5300458e-03 7.9249568e-03 1.9693590e+01 0 5 1 5 2.0
4.7021105e+01 3.4017351e+01 2.8549183e+01 2.4842273e+01 2.4605516e+01 2.2513490e+01 2.1428106e+01 2.0791151e+01 1.8956646e+01 2.4518952e+01 2.0729039e+01 7.5145964e+01 6.6431818e+01 5.2662162e+01 3.7022015e+01 4.5436628e+01 4.8035999e+01 4.0072213e+01 3.2192061e+01 7.2625737e+01 6.1205873e+01 4.5835721e+01 3.8642084e+01 2.9947132e+01 4.4114127e+01 5.4168672e+01 3.7180335e+01 3.2877854e+01 2.8552558e+01 2.4147819e+01 2.0674371e+01 1.8947702e+01 -4.6698104e+00 -2.4039011e+00 -1.4320101e+02 -1.3046019e+02 1.3330771e+02 -4.9805759e+01 8.1309438e-01 0.0000000e+00 1.0000000e+01 6.0603449e+03 4.3935837e+00 0.0000000e+00 8.1280571e-01 4.6548136e+00 9.4780662e-01 -7.9940091e-01 3.5997144e+02 1.6664060e-02 2.6637053e+02 -2.8951850e+01 5.0758087e+00 -3.1022000e+00 -2.5300458e-03 7.9249568e-03 1.9693590e+01 0 6 2 5 2.0
R062 Z087 Y106 J129 W146 H158 F184 K213 2MASS_Ks 2MASS_J 2MASS_H Bessell_U Bessell_B Bessell_V Bessell_I Bessell_R Kepler_Kp TESS DECam_z DECam_u DECam_g DECam_r DECam_i DECam_Y Gaia_G_EDR3 Gaia_BP_EDR3 Gaia_RP_EDR3 VISTA_Z VISTA_Y VISTA_J VISTA_H VISTA_Ks mul mub Vr U V W iMass CL age Teff logg pop Mass Mbol Radius [Fe/H] l b RA2000.0 DEC2000.0 Dist x y z A_Ks [alpha/Fe] ID Is_Binary primary_ID combined_logP
2.5212534e+01 2.3437151e+01 2.2946926e+01 2.2698885e+01 2.2737316e+01 2.2564209e+01 2.2718139e+01 2.2750813e+01 2.0916308e+01 2.1813254e+01 2.1137727e+01 2.8960719e+01 2.7692111e+01 2.6146455e+01 2.3327938e+01 2.4879330e+01 2.4833463e+01 2.3528349e+01 2.3269717e+01 2.8460170e+01 2.6830101e+01 2.5344168e+01 2.3886079e+01 2.3095472e+01 2.4810155e+01 2.6388821e+01 2.3603958e+01 2.2911913e+01 2.2447639e+01 2.1762028e+01 2.1155567e+01 2.0943504e+01 5.4187211e-02 3.8186918e+00 -1.1389063e+02 -1.0081186e+02 2.4678124e+02 9.1264341e+01 1.3530942e-01 0.0000000e+00 1.0000000e+01 3.1466277e+03 5.1644453e+00 0.0000000e+00 1.3530814e-01 1.1389806e+01 1.5813397e-01 -9.4970712e-02 3.2006745e-03 -3.7644077e-03 2.6640150e+02 -2.8931190e+01 2.9168337e+00 -5.2611722e+00 1.6294106e-04 1.1155346e-02 0.0000000e+00 0 1 1 1 1.0
1.8280023e+01 1.8068850e+01 1.8049266e+01 1.8055254e+01 1.8117239e+01 1.8116642e+01 1.8302014e+01 1.8562267e+01 1.6727762e+01 1.7164161e+01 1.6776748e+01 1.9448572e+01 1.9185598e+01 1.8437426e+01 1.7656769e+01 1.8021182e+01 1.8199912e+01 1.7754535e+01 1.8063731e+01 2.0042738e+01 1.8749093e+01 1.8215518e+01 1.8096851e+01 1.8045478e+01 1.8284698e+01 1.8650127e+01 1.7755000e+01 1.7576242e+01 1.7436794e+01 1.7135492e+01 1.6781831e+01 1.6731542e+01 5.4187211e-02 3.8186918e+00 -1.1389063e+02 -1.0081186e+02 2.4678124e+02 9.1264341e+01 9.0224882e-01 0.0000000e+00 1.0000000e+01 5.4611661e+03 4.4174184e+00 0.0000000e+00 9.0202770e-01 5.0507352e+00 9.7265615e-01 6.4701074e-02 3.5999997e+02 -3.7644077e-03 2.6640744e+02 -2.8938149e+01 4.5983030e+00 -3.5797075e+00 -2.6445424e-06 7.1391942e-03 0.0000000e+00 0 2 2 1 1.0
2.7189580e+01 2.4975054e+01 2.4260565e+01 2.3968756e+01 2.4030988e+01 2.3845912e+01 2.4039567e+01 2.3989889e+01 2.2155384e+01 2.3048865e+01 2.2390443e+01 3.1118061e+01 3.0030954e+01 2.8490833e+01 2.5036992e+01 2.6885617e+01 2.6681963e+01 2.5118838e+01 2.4731204e+01 3.0059395e+01 2.9036582e+01 2.7540074e+01 2.5635858e+01 2.4463607e+01 2.6583638e+01 2.8723106e+01 2.5259802e+01 2.4469663e+01 2.3817850e+01 2.2989283e+01 2.2414511e+01 2.2190391e+01 -6.5516244e+00 1.1716060e+00 -7.9343188e+01 -6.6373337e+01 9.2833791e+01 3.5265923e+01 1.4345340e-01 0.0000000e+00 1.0000000e+01 2.9315876e+03 5.1305404e+00 0.0000000e+00 1.4345205e-01 1.1600987e+01 1.6530046e-01 1.6760650e-01 4.3851388e-03 -2.5059108e-03 2.6640884e+02 -2.8933722e+01 4.9185785e+00 -3.2594326e+00 3.7644395e-04 6.5604172e-03 0.0000000e+00 0 3 0 0 0.0
2.6432685e+01 2.4491108e+01 2.3915671e+01 2.3656481e+01 2.3706363e+01 2.3533906e+01 2.3701900e+01 2.3710237e+01 2.1875732e+01 2.2758205e+01 2.2099233e+01 3.0094746e+01 2.8982746e+01 2.7485130e+01 2.4443064e+01 2.6113111e+01 2.6006401e+01 2.4604554e+01 2.4293562e+01 2.9474944e+01 2.8101540e+01 2.6642829e+01 2.5017614e+01 2.4081378e+01 2.5955676e+01 2.7725745e+01 2.4703953e+01 2.3972942e+01 2.3432310e+01 2.2704340e+01 2.2119082e+01 2.1905447e+01 -7.7780939e+00 -2.3327942e-01 -2.3962213e+01 -1.1064623e+01 6.4507357e+01 2.3963224e+00 1.5178442e-01 0.0000000e+00 1.0000000e+01 3.0756073e+03 5.1140763e+00 0.0000000e+00 1.5178288e-01 1.1246362e+01 1.7682473e-01 8.4404856e-02 2.6359830e-03 5.2891509e-03 2.6640020e+02 -2.8931154e+01 4.9113800e+00 -3.2666297e+00 2.2595581e-04 7.2438851e-03 0.0000000e+00 0 4 0 0 0.0
4.7021105e+01 3.4017351e+01 2.8549183e+01 2.4842273e+01 2.4605516e+01 2.2513490e+01 2.1428106e+01 2.0791151e+01 1.8956646e+01 2.4518952e+01 2.0729039e+01 7.5145964e+01 6.6431818e+01 5.2662162e+01 3.7022015e+01 4.5436628e+01 4.8035999e+01 4.0072213e+01 3.2192061e+01 7.2625737e+01 6.1205873e+01 4.5835721e+01 3.8642084e+01 2.9947132e+01 4.4114127e+01 5.4168672e+01 3.7180335e+01 3.2877854e+01 2.8552558e+01 2.4147819e+01 2.0674371e+01 1.8947702e+01 -9.0335610e+00 -2.7360242e+00 -2.0160392e+02 -1.9107442e+02 5.1533963e+01 -4.5152342e+01 8.1309438e-01 0.0000000e+00 1.0000000e+01 6.0603449e+03 4.3935837e+00 0.0000000e+00 8.1280571e-01 4.6548136e+00 9.4780662e-01 -7.9940091e-01 3.5997144e+02 1.6664060e-02 2.6637053e+02 -2.8951850e+01 5.0758087e+00 -3.1022000e+00 -2.5300458e-03 7.9249568e-03 0.0000000e+00 0 5 1 5 3.0
3.1793245e+01 2.7449580e+01 2.5641867e+01 2.4639045e+01 2.4657181e+01 2.4083239e+01 2.4042948e+01 2.3798342e+01 2.1963837e+01 2.3810243e+01 2.2533581e+01 0.0000000e+00 0.0000000e+00 3.4035114e+01 2.8110429e+01 3.1294101e+01 3.1417767e+01 2.8566321e+01 2.6860705e+01 3.7798231e+01 3.5635318e+01 3.2055912e+01 2.8903792e+01 2.6126297e+01 3.0666724e+01 3.4440840e+01 2.8305075e+01 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 -9.0335610e+00 -2.7360242e+00 -2.0160392e+02 -1.9107442e+02 5.1533963e+01 -4.5152342e+01 2.0027892e-01 0.0000000e+00 1.0000000e+01 2.8605457e+03 5.0486657e+00 0.0000000e+00 2.0027673e-01 1.1224508e+01 2.0647986e-01 3.3736235e-01 3.5979544e+02 1.6664060e-02 2.6785368e+02 -2.9934996e+01 5.0758087e+00 -3.1022000e+00 -2.5300458e-03 7.9249568e-03 0.0000000e+00 0 6 2 5 3.0
146 changes: 145 additions & 1 deletion smoke_test/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,78 @@ def _parse_header(lc_file: Path) -> Tuple[List[float] | None, List[float] | None
return planet_vals, event_vals


def _sanity_check_flux_conservation(
lc_file: Path,
true_flux: np.ndarray,
src1_flux: np.ndarray | None,
src2_flux: np.ndarray | None,
abs_tol: float = 1e-5,
) -> None:
"""Check that true_relative_flux ~= src1 + src2 + fblend for a couple of epochs.

This is a strict, non-configurable sanity check. It only runs when both
source1/source2 columns exist and the header contains #fs and #fs2. On
failure it raises SmokeTestError so CI/smoke-test runner fails.
"""
# Only run when both source columns are present
if src1_flux is None or src2_flux is None:
return

fs = None
fs2 = None
with lc_file.open(encoding="utf-8") as header_reader:
for raw in header_reader:
if not raw.startswith("#"):
break
s = raw.strip()
if s.startswith("#fs:"):
parts = s.split()
if len(parts) >= 2:
try:
fs = float(parts[1])
except Exception:
fs = None
elif s.startswith("#fs2:"):
parts = s.split()
if len(parts) >= 2:
try:
fs2 = float(parts[1])
except Exception:
fs2 = None

if fs is None or fs2 is None:
# If header doesn't provide both, skip the strict check
return

fblend = 1.0 - float(fs) - float(fs2)

# choose representative epochs: first epoch and the epoch of peak true flux
try:
peak_idx = int(np.nanargmax(true_flux))
except Exception:
peak_idx = 0

indices = [0]
if peak_idx != 0:
indices.append(int(peak_idx))

for idx in indices:
try:
expected = float(src1_flux[idx]) + float(src2_flux[idx]) + float(fblend)
truev = float(true_flux[idx])
except Exception:
# If indexing or conversion fails, raise an error to surface the issue
raise SmokeTestError(
f"Flux sanity check failed: could not index/convert epoch {idx} in {lc_file.name}"
)
diff = abs(truev - expected)
if diff > abs_tol:
raise SmokeTestError(
f"Flux sanity check failed for {lc_file.name} at epoch index {idx}: true={truev:.8f}, expected={expected:.8f}, abs_diff={diff:.8e}, abs_tol={abs_tol}"
)



def _plot_photometry_only(
lc_file: Path,
output_dir: Path,
Expand All @@ -81,6 +153,8 @@ def _plot_photometry_only(
flux: np.ndarray,
flux_err: np.ndarray,
true_flux: np.ndarray | None,
src1_flux: np.ndarray | None = None,
src2_flux: np.ndarray | None = None,
) -> Path:
fig, ax = plt.subplots(1, 1, figsize=(10, 6))
fig.suptitle(title, fontsize=14)
Expand All @@ -106,6 +180,28 @@ def _plot_photometry_only(
zorder=2,
alpha=0.8,
)
if src1_flux is not None:
ax.plot(
time,
src1_flux,
"-",
linewidth=1.2,
color="magenta",
label="Source 1",
zorder=4,
alpha=0.7,
)
if src2_flux is not None:
ax.plot(
time,
src2_flux,
"-",
linewidth=1.2,
color="gold",
label="Source 2",
zorder=5,
alpha=0.7,
)
ax.axhline(1.0, color="k", linestyle="--", linewidth=1.5, label="Baseline", zorder=3)
ax.set_xlabel("Time (days)")
ax.set_ylabel("Relative Flux")
Expand Down Expand Up @@ -408,6 +504,8 @@ def _render_astrometric_figure(
true_y_vals: np.ndarray | None,
meas_x: np.ndarray | None,
meas_y: np.ndarray | None,
src1_flux: np.ndarray | None = None,
src2_flux: np.ndarray | None = None,
) -> Tuple[Path, Path | None]:
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
fig.suptitle(title, fontsize=14)
Expand Down Expand Up @@ -438,6 +536,28 @@ def _render_astrometric_figure(
zorder=2,
alpha=0.8,
)
if src1_flux is not None:
ax_light.plot(
time,
src1_flux,
"-",
linewidth=1.2,
color="magenta",
label="Source 1",
zorder=4,
alpha=0.7,
)
if src2_flux is not None:
ax_light.plot(
time,
src2_flux,
"-",
linewidth=1.2,
color="gold",
label="Source 2",
zorder=5,
alpha=0.7,
)
ax_light.axhline(
1.0,
color="k",
Expand Down Expand Up @@ -695,6 +815,13 @@ def plot_lightcurves(
if val is not None:
astrometry_expected = str(val).strip().lower() not in {"0", "false", "off"}

# Determine whether MULTIPLE_SOURCES was requested in the parameter file.
multiple_sources_expected = False
if params:
ms = params.get("MULTIPLE_SOURCES")
if ms is not None:
multiple_sources_expected = str(ms).strip().lower() not in {"0", "false", "off"}

for lc_file in lc_files:
planet_vals, event_vals = _parse_header(lc_file)
df = pd.read_csv(lc_file, sep=r"\s+", comment="#")
Expand Down Expand Up @@ -799,8 +926,23 @@ def _optional_column(name: str) -> np.ndarray | None:
f"Smoke test failed: astrometric columns missing in {lc_file.name}"
)

# Extract source flux columns (optional for binary source events)
src1_flux = _optional_column("source1_relative_flux")
src2_flux = _optional_column("source2_relative_flux")

# If the parameter file did not request multiple sources, ignore any
# source1/source2 columns that may nevertheless appear in the output
# (prevents plotting Source 1/Source 2 when MULTIPLE_SOURCES isn't set).
if not multiple_sources_expected:
src1_flux = None
src2_flux = None

# Strict flux-conservation sanity check (non-configurable). Only run
# when multiple sources are expected and both columns are present.
_sanity_check_flux_conservation(lc_file, true_flux, src1_flux, src2_flux)

if not has_astrom:
_plot_photometry_only(lc_file, output_dir, title, time, flux, flux_err, true_flux)
_plot_photometry_only(lc_file, output_dir, title, time, flux, flux_err, true_flux, src1_flux, src2_flux)
continue

true_N_mas = _require_column("true_N_centroid_mas")
Expand Down Expand Up @@ -945,6 +1087,8 @@ def _optional_column(name: str) -> np.ndarray | None:
true_y_vals,
meas_x,
meas_y,
src1_flux,
src2_flux,
)

if astrometry_expected:
Expand Down
4 changes: 3 additions & 1 deletion smoke_test/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ def _resolve_case_selection(raw_choices: Sequence[str] | None, ci_mode: bool = F
("smoke_std", "gulls_std.x", "smoke_std.prm"),
("smoke_std_binary", "gulls_std.x", "smoke_std_binary.prm"),
("smoke_fish", "gullsFish.x", "smoke_fish.prm"),
("smoke_fish_binary", "gullsFish.x", "smoke_std_binary.prm"),
# For the fish binary CI case we should use the fish binary
# parameter file so outputs land under the fish/ output tree.
("smoke_fish_binary", "gullsFish.x", "smoke_fish_binary.prm"),
("smoke_croin", "gulls_croin.x", "smoke_croin.prm"),
("smoke_croin_binary", "gulls_croin.x", "smoke_croin_binary.prm"),
)
Expand Down
Loading
Loading