cosmo/backend/scripts/add_binary_systems.py

488 lines
17 KiB
Python
Raw Normal View History

2025-12-08 10:55:38 +00:00
#!/usr/bin/env python3
"""
补全高价值双星/多星系统数据
包含8-10个科学价值最高的多恒星系统
"""
import asyncio
import asyncpg
import json
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# 数据库连接配置
DB_CONFIG = {
"host": "localhost",
"port": 5432,
"user": "postgres",
"password": "postgres",
"database": "cosmo_db"
}
# 高价值多恒星系统数据(基于天文学资料)
MULTI_STAR_SYSTEMS = {
# 1. Alpha Centauri (比邻星系统) - 已完成,保留用于验证
479: {
"stars": [
{
"id": "star-479-primary",
"name": "Alpha Centauri A",
"name_zh": "南门二A",
"description": "该恒星系主序星,光谱类型: G2V, 表面温度: 5790K",
"extra_data": {
"spectral_type": "G2V",
"mass_solar": 1.1,
"radius_solar": 1.22,
"temperature_k": 5790
}
},
{
"id": "star-479-secondary",
"name": "Alpha Centauri B",
"name_zh": "南门二B",
"description": "与南门二A相互绕转的明亮双星是该系统的主体。",
"extra_data": {
"spectral_type": "K1V",
"mass_solar": 0.93,
"radius_solar": 0.86,
"temperature_k": 5260
}
},
{
"id": "star-479-tertiary",
"name": "Proxima Centauri",
"name_zh": "比邻星",
"description": "一颗质量小、光度弱的红矮星距离南门二A/B约0.2光年,围绕它们公转。",
"extra_data": {
"spectral_type": "M5.5V",
"mass_solar": 0.12,
"radius_solar": 0.14,
"temperature_k": 2900
}
}
]
},
# 2. 55 Cancri (巨蟹座55) - 双星系统
11: {
"stars": [
{
"id": "star-11-primary",
"name": "55 Cancri A",
"name_zh": "巨蟹座55A",
"description": "类太阳黄矮星拥有5颗已确认行星包括著名的超级地球55 Cnc e。",
"extra_data": {
"spectral_type": "G8V",
"mass_solar": 0.95,
"radius_solar": 0.94,
"temperature_k": 5196
}
},
{
"id": "star-11-secondary",
"name": "55 Cancri B",
"name_zh": "巨蟹座55B",
"description": "红矮星伴星距离A星约1065 AU轨道周期约1000年。",
"extra_data": {
"spectral_type": "M4V",
"mass_solar": 0.13,
"radius_solar": 0.30,
"temperature_k": 3200,
"separation_au": 1065,
"orbital_period_years": 1000
}
}
]
},
# 3. 16 Cygni (天鹅座16) - 双星系统
5: {
"stars": [
{
"id": "star-5-primary",
"name": "16 Cygni A",
"name_zh": "天鹅座16A",
"description": "类太阳黄矮星,该双星系统的主星。",
"extra_data": {
"spectral_type": "G1.5V",
"mass_solar": 1.11,
"radius_solar": 1.24,
"temperature_k": 5825
}
},
{
"id": "star-5-secondary",
"name": "16 Cygni B",
"name_zh": "天鹅座16B",
"description": "类太阳黄矮星拥有一颗高偏心率轨道的行星16 Cyg B b展示了双星引力对行星轨道的影响。",
"extra_data": {
"spectral_type": "G2.5V",
"mass_solar": 1.07,
"radius_solar": 1.14,
"temperature_k": 5750,
"separation_au": 850,
"orbital_period_years": 18200
}
}
]
},
# 4. Epsilon Indi (天园增四) - 三体系统 (1恒星 + 2棕矮星)
40: {
"stars": [
{
"id": "star-40-primary",
"name": "Epsilon Indi A",
"name_zh": "天园增四A",
"description": "橙矮星第五近的恒星系统伴有两颗棕矮星Ba和Bb",
"extra_data": {
"spectral_type": "K5V",
"mass_solar": 0.76,
"radius_solar": 0.73,
"temperature_k": 4630
}
},
{
"id": "star-40-secondary",
"name": "Epsilon Indi Ba",
"name_zh": "天园增四Ba",
"description": "T1V型棕矮星距离A星约1460 AU与Bb组成棕矮星双星系统。",
"extra_data": {
"spectral_type": "T1V",
"mass_jupiter": 47,
"radius_jupiter": 0.91,
"temperature_k": 1300,
"separation_from_A_au": 1460,
"is_brown_dwarf": True
}
},
{
"id": "star-40-tertiary",
"name": "Epsilon Indi Bb",
"name_zh": "天园增四Bb",
"description": "T6V型棕矮星与Ba互绕周期约15年是最近的棕矮星双星系统。",
"extra_data": {
"spectral_type": "T6V",
"mass_jupiter": 28,
"radius_jupiter": 0.80,
"temperature_k": 880,
"orbital_period_years": 15,
"is_brown_dwarf": True
}
}
]
},
# 5. Gamma Cephei (仙王座γ) - 双星系统
49: {
"stars": [
{
"id": "star-49-primary",
"name": "Gamma Cephei A",
"name_zh": "仙王座γA",
"description": "亚巨星最早被怀疑有行星的恒星之一1988年拥有一颗类木行星。",
"extra_data": {
"spectral_type": "K1IV",
"mass_solar": 1.59,
"radius_solar": 4.9,
"temperature_k": 4800
}
},
{
"id": "star-49-secondary",
"name": "Gamma Cephei B",
"name_zh": "仙王座γB",
"description": "红矮星伴星距离A星约20 AU轨道周期约66年形成紧密双星系统。",
"extra_data": {
"spectral_type": "M4V",
"mass_solar": 0.4,
"radius_solar": 0.40,
"temperature_k": 3200,
"separation_au": 20,
"orbital_period_years": 66
}
}
]
},
# 6. Upsilon Andromedae (仙女座υ) - 双星系统
572: {
"stars": [
{
"id": "star-572-primary",
"name": "Upsilon Andromedae A",
"name_zh": "仙女座υA",
"description": "黄白主序星第一个被发现有多颗行星的主序星1999年拥有4颗已确认行星。",
"extra_data": {
"spectral_type": "F8V",
"mass_solar": 1.27,
"radius_solar": 1.63,
"temperature_k": 6212
}
},
{
"id": "star-572-secondary",
"name": "Upsilon Andromedae B",
"name_zh": "仙女座υB",
"description": "红矮星伴星距离A星约750 AU。",
"extra_data": {
"spectral_type": "M4.5V",
"mass_solar": 0.25,
"radius_solar": 0.28,
"temperature_k": 3100,
"separation_au": 750
}
}
]
},
# 7. HD 41004 - 双星系统两个独立的system_id需要合并
347: {
"stars": [
{
"id": "star-347-primary",
"name": "HD 41004 A",
"name_zh": "HD 41004 A",
"description": "橙矮星拥有一颗类木行星HD 41004 A b。",
"extra_data": {
"spectral_type": "K1V",
"mass_solar": 0.70,
"radius_solar": 0.67,
"temperature_k": 5000
}
},
{
"id": "star-347-secondary",
"name": "HD 41004 B",
"name_zh": "HD 41004 B",
"description": "红矮星伴星距离A星约23 AU可能拥有棕矮星伴星。",
"extra_data": {
"spectral_type": "M2V",
"mass_solar": 0.40,
"radius_solar": 0.39,
"temperature_k": 3400,
"separation_au": 23
}
}
]
},
# 8. GJ 86 (格利泽86) - 双星系统(橙矮星 + 白矮星)
128: {
"stars": [
{
"id": "star-128-primary",
"name": "GJ 86 A",
"name_zh": "格利泽86A",
"description": "橙矮星拥有一颗类木行星GJ 86 b伴星是罕见的白矮星。",
"extra_data": {
"spectral_type": "K1V",
"mass_solar": 0.79,
"radius_solar": 0.77,
"temperature_k": 5100
}
},
{
"id": "star-128-secondary",
"name": "GJ 86 B",
"name_zh": "格利泽86B",
"description": "白矮星伴星距离A星约21 AU是研究恒星演化对行星影响的重要案例。",
"extra_data": {
"spectral_type": "DA (白矮星)",
"mass_solar": 0.55,
"radius_solar": 0.01,
"temperature_k": 8000,
"separation_au": 21,
"is_white_dwarf": True
}
}
]
},
# 9. HD 196885 - 双星系统
267: {
"stars": [
{
"id": "star-267-primary",
"name": "HD 196885 A",
"name_zh": "HD 196885 A",
"description": "黄白主序星拥有一颗行星HD 196885 A b。",
"extra_data": {
"spectral_type": "F8V",
"mass_solar": 1.33,
"radius_solar": 1.68,
"temperature_k": 6172
}
},
{
"id": "star-267-secondary",
"name": "HD 196885 B",
"name_zh": "HD 196885 B",
"description": "红矮星伴星距离A星约25 AU。",
"extra_data": {
"spectral_type": "M",
"mass_solar": 0.45,
"radius_solar": 0.43,
"temperature_k": 3500,
"separation_au": 25
}
}
]
}
}
async def add_missing_stars(conn):
"""添加缺失的恒星"""
logger.info("=" * 80)
logger.info("开始补全多恒星系统数据")
logger.info("=" * 80)
added_count = 0
skipped_count = 0
for system_id, system_data in MULTI_STAR_SYSTEMS.items():
# 检查系统是否存在
system = await conn.fetchrow(
"SELECT id, name, name_zh FROM star_systems WHERE id = $1",
system_id
)
if not system:
logger.warning(f"\n⚠️ 系统ID={system_id}不存在,跳过")
continue
logger.info(f"\n{'='*80}")
logger.info(f"处理恒星系统: {system['name_zh'] or system['name']} (ID={system_id})")
logger.info(f"{'='*80}")
for star in system_data["stars"]:
# 检查是否已存在
existing = await conn.fetchrow(
"SELECT id FROM celestial_bodies WHERE id = $1",
star["id"]
)
if existing:
logger.info(f" ✓ 恒星已存在: {star['name_zh']} ({star['id']})")
skipped_count += 1
else:
# 插入新恒星
await conn.execute("""
INSERT INTO celestial_bodies
(id, name, name_zh, type, system_id, description, is_active, extra_data, created_at, updated_at)
VALUES
($1, $2, $3, 'star', $4, $5, TRUE, $6::jsonb, NOW(), NOW())
""",
star["id"],
star["name"],
star["name_zh"],
system_id,
star["description"],
json.dumps(star["extra_data"])
)
logger.info(f" ✅ 添加恒星: {star['name_zh']} ({star['id']})")
added_count += 1
logger.info(f"\n{'='*80}")
logger.info(f"恒星数据补全完成!")
logger.info(f" 新增: {added_count}")
logger.info(f" 跳过: {skipped_count}颗(已存在)")
logger.info(f"{'='*80}")
async def verify_results(conn):
"""验证结果"""
logger.info("\n" + "=" * 80)
logger.info("验证多星系统数据")
logger.info("=" * 80)
system_ids = list(MULTI_STAR_SYSTEMS.keys())
rows = await conn.fetch("""
SELECT
s.id,
s.name,
s.name_zh,
COUNT(CASE WHEN cb.type = 'star' THEN 1 END) as star_count,
COUNT(CASE WHEN cb.type = 'planet' THEN 1 END) as planet_count,
COUNT(CASE WHEN cb.is_active = TRUE THEN 1 END) as active_count,
string_agg(
CASE WHEN cb.type = 'star' THEN cb.name_zh || ' (' || cb.id || ')' END,
', '
ORDER BY cb.id
) as star_names
FROM star_systems s
LEFT JOIN celestial_bodies cb ON s.id = cb.system_id
WHERE s.id = ANY($1)
GROUP BY s.id, s.name, s.name_zh
ORDER BY s.id
""", system_ids)
print(f"\n{'系统ID':<8} {'系统名称':<30} {'恒星数':<8} {'行星数':<8} {'启用数':<8}")
print("=" * 100)
for row in rows:
system_name = row['name_zh'] or row['name']
print(f"{row['id']:<8} {system_name:<30} {row['star_count']:<8} {row['planet_count']:<8} {row['active_count']:<8}")
# 详细显示每个系统的恒星
print(f"\n{'='*100}")
print("各系统恒星详情:")
print(f"{'='*100}")
for row in rows:
system_name = row['name_zh'] or row['name']
stars = await conn.fetch("""
SELECT id, name, name_zh, extra_data
FROM celestial_bodies
WHERE system_id = $1 AND type = 'star'
ORDER BY id
""", row['id'])
print(f"\n{system_name} (ID={row['id']}):")
for star in stars:
# Handle both dict and JSON string
extra = star['extra_data']
if isinstance(extra, str):
extra = json.loads(extra) if extra else {}
elif extra is None:
extra = {}
spectral = extra.get('spectral_type', 'N/A')
mass = extra.get('mass_solar', extra.get('mass_jupiter'))
mass_unit = 'M☉' if 'mass_solar' in extra else ('MJ' if 'mass_jupiter' in extra else '')
print(f"{star['name_zh']:<25} | 光谱: {spectral:<10} | 质量: {mass}{mass_unit if mass else 'N/A'}")
async def main():
"""主函数"""
print("\n" + "=" * 80)
print("多恒星系统数据补全脚本 v2.0")
print("将补全8-10个高价值双星/多星系统")
print("=" * 80)
conn = await asyncpg.connect(**DB_CONFIG)
try:
# 1. 添加缺失的恒星
await add_missing_stars(conn)
# 2. 验证结果
await verify_results(conn)
print("\n" + "=" * 80)
print("✅ 所有操作完成!")
print("=" * 80)
except Exception as e:
logger.error(f"❌ 发生错误: {e}")
import traceback
traceback.print_exc()
finally:
await conn.close()
if __name__ == "__main__":
asyncio.run(main())