End-to-end Python data engineering and ML pipeline for orbital proximity detection, collision risk scoring, brightness modeling, and Power BI dashboard visualization across Starlink megaconstellation datasets.
Python Pandas NumPy SciPy KD-Tree SGP4 Skyfield Scikit-learn Plotly Power BI
This project builds a complete analysis pipeline to detect and prioritize satellite collision risks in dense Low Earth Orbit (LEO) constellations. It fetches live TLE orbital data, propagates satellite trajectories using SGP4, applies KD-Tree spatial indexing for fast proximity detection, trains ML classifiers for collision prediction and brightness calibration, and exports everything into a three-page interactive Power BI dashboard.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Starlink_Optimized_Pipeline.py β
β ββ Run this FIRST ββ β
β β
β Section 1 β Setup & Imports β
β Section 2 β TLE Fetch from CelesTrak β
β Section 3 β SGP4 Orbital Propagation β
β Section 4 β Altitude Density Analysis β
β Section 5 β KD-Tree Proximity Detection [O(n log n)] β
β Section 6 β Satellite Brightness Modeling β
β Section 7 β SatNOGS Fetch & Calibration β
β Section 8 β ML Brightness Predictor (Gradient Boosting) β
β Section 9 β Collision Risk Scoring & ML Classifier β
β Section 10 β Synthetic Constellation (100 sats Γ 300 frames)β
β Section 11 β Plotly Interactive Dashboard (HTML) β
β Section 12 β Power BI Export (6 structured CSVs) β
β Section 13 β Summary & ZIP Export β
βββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β generates
βΌ
multi_satellite_dataset.csv
collision_risk.csv
passes_calibrated.csv
calibration_data.csv
collision_features.csv
pbi_satellite_master.csv
pbi_collision_events.csv
pbi_risk_summary.csv
pbi_orbital_density.csv
pbi_launch_timeline.csv
pbi_kpi_summary.csv
starlink_dashboard.html
roc_pr_curves.png
altitude_density.png
β
βββββββββββββββ
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β powerbi_export.py β
β ββ OPTIONAL: standalone re-export only ββ β
β β
β Use this ONLY when you want to regenerate the 6 Power BI β
β CSVs from the 2 raw input CSVs without re-running the full β
β pipeline above (e.g. to refresh the dashboard quickly). β
β β
β Reads: β
β SpaceX Satellite Dataset.csv β
β multi_satellite_collision_dataset.csv β
β β
β Generates β same 6 pbi_*.csv files β
βββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Power BI Desktop β
β β
β Import the 6 pbi_*.csv files β build relational model β
β OR open Starlink_Dashboard.pbix directly β
β β
β Page 1 β Collision Risk Overview β
β Page 2 β Temporal Trends β
β Page 3 β Orbital Density & KD-Tree Analysis β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Starlink-Collision-Risk-Analysis/
β
βββ Starlink_Optimized_Pipeline.py β Full pipeline (run first)
βββ powerbi_export.py β Standalone PBI export (optional)
βββ Starlink_project_data_science.ipynb β Original notebook (EDA + Plotly)
βββ Starlink_Dashboard.pbix β Power BI Desktop dashboard
β
βββ SpaceX Satellite Dataset.csv β Raw input (902 satellites)
βββ multi_satellite_collision_dataset.csv β Raw input (800 events)
β
βββ powerbi_data/
β βββ pbi_satellite_master.csv β Satellite dimension table
β βββ pbi_collision_events.csv β Encounter fact table
β βββ pbi_risk_summary.csv β Per-satellite risk scores
β βββ pbi_orbital_density.csv β KD-Tree density by altitude
β βββ pbi_launch_timeline.csv β Cumulative launch trend
β βββ pbi_kpi_summary.csv β Single-row KPI summary
β
βββ Dashboard Screenshots/
β βββ page1_collision_risk_overview.png
β βββ page2_temporal_trends.png
β βββ page3_orbital_density.png
β
βββ collision_model.pkl β Trained collision classifier
βββ brightness_gb_model.joblib β Trained brightness predictor
βββ run_summary.json β Pipeline run metadata
βββ README.md
pip install sgp4 skyfield pandas numpy matplotlib scipy requests tqdm scikit-learn plotly python-dateutil joblib seabornIn Google Colab:
!pip install -q sgp4 skyfield pandas numpy matplotlib scipy requests tqdm scikit-learn plotly python-dateutil joblib seabornpython Starlink_Optimized_Pipeline.pyThis runs all 13 sections end to end and generates every output file automatically. All 6 Power BI CSVs are produced here β you do not need to run powerbi_export.py after this.
What each section produces:
| Section | Output |
|---|---|
| TLE Fetch | starlink_latest.txt |
| SGP4 Propagation | In-memory position DataFrame |
| Altitude Density | altitude_density.png |
| KD-Tree Detection | collision_features.csv |
| Brightness Modeling | Skyfield pass objects |
| SatNOGS Calibration | calibration_data.csv |
| ML Brightness | brightness_gb_model.joblib + passes_calibrated.csv |
| Collision Scoring | collision_risk.csv + roc_pr_curves.png + collision_model.pkl |
| Synthetic Dataset | multi_satellite_dataset.csv |
| Plotly Dashboard | starlink_dashboard.html |
| Power BI Export | All 6 pbi_*.csv files |
| Summary | run_summary.json + starlink_export_all.zip |
Only run this if you want to regenerate the 6 Power BI tables from the 2 raw CSVs without running the full pipeline:
python powerbi_export.pyWhen to use powerbi_export.py:
- You updated the raw CSVs and only need fresh PBI tables
- You want to demo the dashboard without running ML/SGP4
- You are on a machine without SGP4 or Skyfield installed
Reads:
SpaceX Satellite Dataset.csv
multi_satellite_collision_dataset.csv
Generates in ./powerbi_data/:
| File | Description | Rows |
|---|---|---|
pbi_satellite_master.csv |
Orbital params, orbit shell classification | 902 |
pbi_collision_events.csv |
Events with risk tiers, timestamps, positions | 800 |
pbi_risk_summary.csv |
Composite risk scores per satellite | 4 |
pbi_orbital_density.csv |
KD-Tree neighbor counts at 10/50/100 km | 4 |
pbi_launch_timeline.csv |
Cumulative satellite launches over time | 11 |
pbi_kpi_summary.csv |
Single-row headline KPIs for cards | 1 |
- Download Power BI Desktop β free
- Open
Starlink_Dashboard.pbixβ data loads automatically - Or import fresh: Home β Get Data β Text/CSV β load all 6 files from
powerbi_data/
Dashboard Pages:
| Page | Visuals |
|---|---|
| Page 1 β Collision Risk Overview | 4 KPI cards, bar chart of max Pc per satellite, donut chart of risk tier distribution, ranked risk table |
| Page 2 β Temporal Trends | Collision probability over time, event frequency by hour of day, cumulative launch timeline |
| Page 3 β Orbital Density & KD-Tree | Scatter of altitude vs neighbor count, crowded altitude band bar chart, density risk donut, KD-Tree KPI cards |
Replaces O(nΒ²) brute-force pairwise comparison with O(n log n) cKDTree proximity search. At 4,000-satellite Starlink scale this is approximately 166Γ faster than brute force.
tree = cKDTree(coords) # Build: O(n log n)
pairs = tree.query_pairs(r=5.0) # Query: O(n log n)Score = 50% Γ avg_collision_probability (normalised)
+ 30% Γ fraction of critical-tier events
+ 20% Γ historical close encounter count (normalised)
| Tier | Collision Probability |
|---|---|
| Low | < 0.001 |
| Medium | 0.001 β 0.005 |
| High | 0.005 β 0.01 |
| Critical | β₯ 0.01 |
Gradient Boosting Classifier trained on distance_km, rel_speed, range_rate, hist_close_count. Acts as a rapid triage layer β reserves expensive covariance-based Pc computation only for the top flagged pairs.
Gradient Boosting Regressor calibrated against SatNOGS observational records. Predicts apparent visual magnitude per pass using elevation angle and Sunβsatelliteβobserver phase geometry.
| File | Description | Records |
|---|---|---|
SpaceX Satellite Dataset.csv |
Real Starlink orbital parameters, launch info, NORAD numbers | 902 |
multi_satellite_collision_dataset.csv |
Simulated multi-satellite encounter events with 3D ECI positions | 800 |
| Metric | Value |
|---|---|
| Min observed distance | 0.12 km |
| Total collision events | 800 |
| Avg observed distance | 9.57 km |
| Risk distribution | 48.5% Medium, 40.73% Low, 10.76% High |
| KD-Tree complexity | O(n log n) vs O(nΒ²) brute-force |
| Complexity improvement | ~166Γ faster at 4,000-satellite scale |
"I built a Python pipeline using SGP4 propagation and KD-Tree spatial indexing to process orbital datasets and compute satellite proximity at O(n log n) complexity β approximately 166Γ faster than brute force at Starlink scale. I trained a Gradient Boosting classifier for collision triage and a calibrated photometric model for brightness prediction using SatNOGS observations. I then exported six structured tables into Power BI, built a relational star-schema data model, and designed a three-page dashboard covering collision risk distribution, temporal trends, and orbital density analysis by altitude band."
Writick Parui M.E. CSE @ Thapar Institute of Engineering & Technology (TIET), Patiala CGPA: 9.72 | GATE 2025 Qualified | Ex-TCS iON Intern
GitHub: @writickp3-ctrl
For educational and research purposes only.