exovetter-api / pipeline /step5_params.py
ZeroiJ's picture
Upload folder using huggingface_hub
c223e92 verified
Raw
History Blame Contribute Delete
4.31 kB
"""
STEP 5 — Parameter Estimation
Calculate planet radius, orbital distance, and equilibrium temperature.
"""
from typing import Dict, Optional
import numpy as np
# Physical constants
G = 6.67430e-11 # m^3 kg^-1 s^-2
MSUN = 1.98847e30 # kg
RSUN = 6.957e8 # m
AU = 1.495978707e11 # m
REARTH = 6.371e6 # m
def estimate_parameters(
tls_results: Dict,
star_radius: float = 1.0, # Solar radii
star_mass: float = 1.0, # Solar masses
star_temp: float = 5778.0, # Kelvin
) -> Dict:
"""
Estimate planetary parameters from TLS results and stellar properties.
Args:
tls_results: Output from step2_tls.find_period()
star_radius: Stellar radius in solar radii (R_sun)
star_mass: Stellar mass in solar masses (M_sun)
star_temp: Stellar effective temperature in Kelvin
Returns:
Dictionary with:
- planet_radius: Planet radius in Earth radii (R_earth)
- planet_radius_rearth: Alias for planet_radius
- orbital_distance: Semi-major axis in AU
- equilibrium_temperature: Planet equilibrium temperature in K
- orbital_period_days: Orbital period in days
- transit_depth_pct: Transit depth as percentage
- transit_duration_hours: Transit duration in hours
"""
if not tls_results:
return _empty_params()
period_days = tls_results["period"]
depth_raw = tls_results["depth"]
duration_days = tls_results["duration"]
depth_frac = 1.0 - depth_raw
# --- Planet Radius ---
# depth_frac = (Rp / Rstar)^2
# Rp = Rstar * sqrt(depth_frac)
planet_radius_rsun = star_radius * np.sqrt(depth_frac)
planet_radius_rearth = planet_radius_rsun * RSUN / REARTH
# --- Orbital Distance (Kepler's Third Law) ---
# P^2 = (4π^2 / GM) * a^3
# a = (GM * P^2 / 4π^2)^(1/3)
period_seconds = period_days * 86400.0
star_mass_kg = star_mass * MSUN
a_meters = (G * star_mass_kg * period_seconds**2 / (4 * np.pi**2))**(1/3)
orbital_distance_au = a_meters / AU
# --- Equilibrium Temperature ---
# Teq = Tstar * sqrt(Rstar / 2a) * (1 - A)^(1/4)
# Assume Bond albedo A = 0.3 (Earth-like)
albedo = 0.3
star_radius_m = star_radius * RSUN
equilibrium_temperature = star_temp * np.sqrt(
star_radius_m / (2 * a_meters)
) * (1 - albedo)**0.25
return {
"planet_radius": float(planet_radius_rearth),
"planet_radius_rearth": float(planet_radius_rearth),
"orbital_distance": float(orbital_distance_au),
"equilibrium_temperature": float(equilibrium_temperature),
"orbital_period_days": float(period_days),
"transit_depth_pct": float(depth_frac * 100),
"transit_duration_hours": float(duration_days * 24),
}
def _empty_params() -> Dict:
"""Return empty parameter structure for failed detections."""
return {
"planet_radius": 0.0,
"planet_radius_rearth": 0.0,
"orbital_distance": 0.0,
"equilibrium_temperature": 0.0,
"orbital_period_days": 0.0,
"transit_depth_pct": 0.0,
"transit_duration_hours": 0.0,
}
def format_planet_summary(params: Dict, target_name: str = "Candidate") -> str:
"""Generate a formatted planet summary card."""
lines = [
f"{target_name}",
"─" * 32,
f"Period: {params['orbital_period_days']:.2f} days",
f"Radius: {params['planet_radius_rearth']:.2f} R⊕",
f"Orbital Dist: {params['orbital_distance']:.3f} AU",
f"Temperature: {params['equilibrium_temperature']:.0f} K "
f"({params['equilibrium_temperature'] - 273.15:.0f}°C)",
f"Depth: {params['transit_depth_pct']:.3f}%",
f"Duration: {params['transit_duration_hours']:.1f} hours",
]
return "\n".join(lines)
def classify_planet_type(planet_radius_rearth: float) -> str:
"""Classify planet by radius."""
if planet_radius_rearth < 1.25:
return "Earth-sized"
elif planet_radius_rearth < 2.0:
return "Super-Earth"
elif planet_radius_rearth < 4.0:
return "Sub-Neptune"
elif planet_radius_rearth < 8.0:
return "Neptune-sized"
elif planet_radius_rearth < 12.0:
return "Sub-Jupiter"
else:
return "Jupiter-sized"