Strengthen portfolio accuracy and reproducibility - #1
Conversation
52acd1d to
43f4f72
Compare
There was a problem hiding this comment.
Pull request overview
This PR strengthens the project’s “lost-in-space” attitude-solve claims and makes evaluation evidence reproducible by (1) separating camera calibration from physical body roll, (2) standardizing result metadata and residual metrics, and (3) bundling auditable full-test outputs plus CI and regression tests.
Changes:
- Refactors the core solver to remove label-derived roll leakage (CD angle) by factoring CD rotation out of intrinsics and seeding all attitude axes from RANSAC/Wahba.
- Standardizes quality gating on per-star Euclidean pixel residuals and adds explicit result metadata + normalization utilities for legacy artifacts.
- Improves demo/evidence reproducibility via bundled full-test CSV/JSON outputs, Streamlit Replay robustness, new tests, and GitHub Actions CI.
Reviewed changes
Copilot reviewed 31 out of 41 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_streamlit_replay.py | Adds Streamlit AppTest coverage for both successful Replay and quality-gate refusal paths. |
| tests/test_results_contract.py | Adds contract tests asserting bundled demo-set completeness and auditable full-eval counts/summary files. |
| tests/test_core_geometry.py | Adds geometry regression tests for pose/rotation round-trip, CD factorization, and radial residual computation. |
| Results/star_id_run/hlsp_tica_tess_ffi_s1751-o1-01222079-cam3-ccd2_tess_v01_img.json | Updates stored refusal artifact to new roll convention + Euclidean residual metadata. |
| Results/star_id_run/hlsp_tica_tess_ffi_s1751-o1-01222079-cam2-ccd1_tess_v01_img.json | Updates stored solved artifact metadata (residual metric, convention, calibration/seed). |
| Results/star_id_run/hlsp_tica_tess_ffi_s1751-o1-01222079-cam1-ccd4_tess_v01_img.json | Updates stored solved artifact metadata (residual metric, convention, calibration/seed). |
| Results/full_test_per_frame.csv | Adds auditable per-frame outcome table for the full 120-frame evaluation. |
| Results/full_test_metrics.json | Adds machine-readable aggregate evaluation metrics, counts, and provenance. |
| RESULTS.md | Updates documentation to the corrected roll convention and publishes full-eval metrics + exclusions/refusals. |
| requirements.txt | Adds pytest pin while keeping runtime deps (including Streamlit) in requirements. |
| README.md | Updates headline results to full-evaluation numbers and clarifies conventions/limitations and reproducible artifacts. |
| PROJECT_DESCRIPTION.md | Updates portfolio summary to corrected median error and clarifies statistical claims and roll calibration changes. |
| Code/Tess_Dataset/process_tess.py | Removes machine-specific default paths; requires explicit FITS dir and uses repo-relative defaults for outputs/catalog. |
| Code/Streamlit_app/pipeline_app.py | Makes Replay refusal path non-crashing and aligns displayed residuals/pose seeding with updated solver conventions. |
| Code/Star_ID/visualize_pipeline.py | Updates WCS reconstruction to use attitude-free CD intrinsics. |
| Code/Star_ID/visualize_inference.py | Updates overlays/residual plots to use Euclidean residuals and adds a summary-only mode. |
| Code/Star_ID/triangle_id.py | Improves Triangle ID performance via catalog-hash keyed cache, vectorized third-star filtering, and FOV cone culling. |
| Code/Star_ID/summarize_results.py | Adds a script to export an auditable per-frame CSV from JSON artifacts (with legacy-roll correction option). |
| Code/Star_ID/normalize_result_conventions.py | Adds a utility to normalize legacy artifacts to the physical roll convention + Euclidean residual metric. |
| Code/Star_ID/inference_full.py | Core refactor: factor CD rotation out of intrinsics, seed full attitude from RANSAC/Wahba, and gate on radial per-star residuals. |
| Code/Model_train_code/train.py | Removes machine-specific default dataset path by requiring --data-dir. |
| .gitignore | Ignores .pytest_cache/. |
| .github/workflows/ci.yml | Adds CI workflow running compileall + pytest on Python 3.11. |
| .devcontainer/devcontainer.json | Simplifies devcontainer setup to install requirements on create and run Streamlit on attach. |
Comments suppressed due to low confidence (11)
Code/Streamlit_app/pipeline_app.py:257
st.pyplotdoes not acceptwidth="stretch"(Streamlit supportsuse_container_width=True). This is likely to raise at runtime under the allowed dependency range.
st.pyplot(fig, width="stretch")
Code/Streamlit_app/pipeline_app.py:296
st.pyplotdoes not acceptwidth="stretch"(Streamlit supportsuse_container_width=True). Passing a string width here can break Replay/Live rendering.
st.pyplot(fig, width="stretch")
Code/Streamlit_app/pipeline_app.py:325
st.pyplotdoes not acceptwidth="stretch"in Streamlit 1.30; useuse_container_width=Trueto get the same layout behavior across supported versions.
st.pyplot(fig, width="stretch")
Code/Streamlit_app/pipeline_app.py:369
st.pyplotdoes not acceptwidth="stretch"(Streamlit usesuse_container_width=True). Leaving this as-is can cause a runtime exception when the app reaches Stage 2.
st.pyplot(fig, width="stretch")
Code/Streamlit_app/pipeline_app.py:493
st.pyplotdoes not acceptwidth="stretch"(Streamlit usesuse_container_width=True). This can crash Stage 3 rendering under the current requirements range.
st.pyplot(fig, width="stretch")
Code/Streamlit_app/pipeline_app.py:697
st.pyplotdoes not acceptwidth="stretch"(Streamlit usesuse_container_width=True). This is on the final output path, so a failure here would negate an otherwise successful solve.
st.pyplot(fig, width="stretch")
Code/Streamlit_app/pipeline_app.py:457
st.dataframedoes not acceptwidth="stretch"(for responsive sizing useuse_container_width=True).
st.dataframe(angle_table, width="stretch", hide_index=True)
Code/Streamlit_app/pipeline_app.py:476
st.dataframedoes not acceptwidth="stretch"(for responsive sizing useuse_container_width=True).
st.dataframe(angle_table, width="stretch", hide_index=True)
Code/Streamlit_app/pipeline_app.py:556
st.dataframedoes not acceptwidth="stretch"; useuse_container_width=Trueto avoid runtime errors across the supported Streamlit range.
st.dataframe(pd.DataFrame(history), width="stretch", hide_index=True)
Code/Streamlit_app/pipeline_app.py:616
st.dataframedoes not acceptwidth="stretch"; useuse_container_width=Truefor the intended responsive layout.
st.dataframe(pd.DataFrame(history), width="stretch", hide_index=True)
Code/Streamlit_app/pipeline_app.py:666
- This call passes
width="stretch"tost.dataframe, but Streamlit expects a numericwidthhere. Useuse_container_width=Truefor consistent responsive behavior.
}), width="stretch", hide_index=True)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| st.markdown("---") | ||
| run_btn = st.button("▶️ Run pipeline", type="primary", | ||
| use_container_width=True) | ||
| run_btn = st.button("▶️ Run pipeline", type="primary", width="stretch") |
| show_image_with_overlay(ax, img_np, vmin, vmax, | ||
| f"{img_w}×{img_h} • TESS ({img_path.name if img_path else 'uploaded'})") | ||
| st.pyplot(fig, use_container_width=True) | ||
| st.pyplot(fig, width="stretch") |
| "flux": f"{det_b[top_idx[i]]:.1f}", | ||
| }) | ||
| st.dataframe(pd.DataFrame(sample), use_container_width=True, hide_index=True) | ||
| st.dataframe(pd.DataFrame(sample), width="stretch", hide_index=True) |
| boresight = R @ np.array([1.0, 0.0, 0.0]) | ||
| cone_cos = np.cos(np.radians(12.0)) | ||
| cat_idx = np.where(self.db.star_vecs @ boresight >= cone_cos)[0] |
What changed
Why
The previous portfolio version described true lost-in-space solving while the plate-solve roll seed still came from label WCS. It also showed only a 16-frame demo despite a larger evaluation being available, and one rejected replay case crashed. This change aligns the implementation with the claim and makes the reported evidence reproducible.
Results
The previously quoted 7.35 arcsec full-test median used the FITS CD angle as physical roll. The corrected body-roll convention is now documented and applied consistently.
Validation
python -m compileall -q Code testspytest -q— 7 passedgit diff --checkScope
Pyramid matching is intentionally not included in this PR; it will be added only after its thesis-side evaluation is complete.