mcpField
S
sunpy

sunpy

github.com/tondevrel数据与数据库2447 次安装38 周前更新
代码仓库

关于 sunpy

SunPy 是基于 Astropy 生态构建的太阳物理分析工具包,面向处理太阳观测数据的研究人员,整合坐标感知地图、时间序列和跨存储库搜索。

主要功能

  1. 01支持坐标信息的太阳图像地图
  2. 02太阳坐标系转换
  3. 03跨数据源搜索与下载太阳数据
  4. 04时间序列分析
  5. 05太阳图像重投影与旋转

适用场景

  1. 01搜索档案中的太阳观测数据
  2. 02绘制并比较不同仪器的图像
  3. 03分析 GOES X 射线光变曲线
  4. 04校正图像中的太阳自转

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tondevrel/scientific-agent-skills --skill sunpy

安装后在 Claude Code 中输入/sunpy确认已加载。

详细介绍

SunPy - 太阳物理分析

SunPy 基于 Astropy 生态系统构建,并扩展了其中的功能,以满足太阳物理学家的需求。它的核心优势包括用于二维成像数据的 Map 对象、用于光变曲线的 TimeSeries,以及用于跨多个存储库统一搜索数据的 Fido 接口。

适用场景

  • 从 VSO、JSOC 和其他档案中搜索并下载太阳数据。
  • 可视化太阳图像(EUV、磁图、白光)。
  • 在不同太阳坐标系之间转换坐标(例如,从 Stonyhurst 转换到 Helioprojective)。
  • 分析太阳时间序列数据(GOES X 射线通量、太阳黑子计数)。
  • 校正太阳差动自转。
  • 叠加来自不同仪器的数据(例如,AIA 和 HMI)。
  • 对太阳圆面进行边缘拟合和特征追踪。

参考文档

官方文档:https://docs.sunpy.org/
SunPy 示例图库:https://docs.sunpy.org/en/stable/generated/gallery/index.html
搜索模式:sunpy.map.Map、sunpy.net.Fido、sunpy.coordinates.frames、sunpy.timeseries

核心原则

Map 对象

用于二维空间数据的主要数据结构。它将图像数组与元数据(FITS 标头)和坐标参考系统(WCS)结合起来,从而支持物理上准确的绘图和裁剪。

太阳坐标

太阳物理学会使用许多非笛卡尔坐标系。SunPy 会处理将三维太阳位置投影到二维望远镜平面上的计算,并考虑地球相对于太阳的位置。

Fido(Federated IDO)

用于搜索数据的统一接口。你只需定义所需的数据(时间、仪器、波长),Fido 就会自动从不同提供方查找。

快速参考

安装
pip install "sunpy[all]"
标准导入
import sunpy.map
import sunpy.coordinates
from sunpy.net import Fido, attrs as a
import astropy.units as u
from astropy.coordinates import SkyCoord
基本模式 - 搜索、下载和绘图
from sunpy.net import Fido, attrs as a
import sunpy.map

# 1. Search for data
result = Fido.search(a.Time("2011/06/07 06:30", "2011/06/07 06:35"),
                     a.Instrument.aia,
                     a.Wavelength(171*u.angstrom))

# 2. Download (returns list of file paths)
# downloaded_files = Fido.fetch(result)

# 3. Create and plot map
# aiayamap = sunpy.map.Map(downloaded_files[0])
# aiayamap.peek()

关键规则

✅ 应该做
  • 使用 sunpy.map.Map - 这是唯一可靠的方式,可以正确处理带有坐标元数据的太阳图像。
  • 使用物理单位 - 波长、距离和时间始终使用 astropy.units。
  • 检查观测者信息 - 太阳坐标取决于观测者(通常是地球或卫星)所在的位置。请确保地图标头包含有效的观测者元数据。
  • 对地图进行归一化 - 比较图像时,使用 map.plot(norm=...) 或 aiamap.exposure_time,以考虑不同的曝光时间。
  • 向量化坐标转换 - SkyCoord 数组的速度远快于逐点转换。
  • 使用 Fido 下载 - 它可以无缝处理重试、本地缓存和多个提供方。
❌ 不应该做
  • 使用原始 plt.imshow 绘图 - 这会忽略世界坐标系统(WCS)。请改用 ax = plt.subplot(projection=my_map)。
  • 忽略时间尺度 - 与 Astropy 一样,请注意 UTC 和 TAI 的区别。
  • 将波长硬编码 - 使用 a.Wavelength(193 * u.AA),确保搜索会考虑单位。
  • 手动裁剪 - 不要切片处理 numpy 数组;请使用 my_map.submap(bottom_left, top_right) 来保留坐标元数据。

反模式(切勿使用)

# ❌ BAD: Manual cropping by pixel indices
# cropped_data = my_map.data[100:200, 300:400] # Coordinates lost!

# ✅ GOOD: Submap using SkyCoord
from astropy.coordinates import SkyCoord
bottom_left = SkyCoord(-500*u.arcsec, -500*u.arcsec, frame=my_map.coordinate_frame)
top_right = SkyCoord(500*u.arcsec, 500*u.arcsec, frame=my_map.coordinate_frame)
submap = my_map.submap(bottom_left, top_right=top_right)

# ❌ BAD: Hardcoding solar radius or distance
# distance = 1.496e11 # meters

# ✅ GOOD: Get from map or constants
from sunpy.coordinates import sun
dist = my_map.dsun # Distance to Sun at observation time

太阳地图(sunpy.map)

操作与可视化
import sunpy.map
import matplotlib.pyplot as plt

# Load map
aia_map = sunpy.map.Map("aia_data.fits")

# Coordinate-aware plotting
fig = plt.figure()
ax = fig.add_subplot(projection=aia_map)
aia_map.plot(ax=ax)
aia_map.draw_limb(ax=ax, color='white')
aia_map.draw_grid(ax=ax, color='white', linestyle='dotted')

# Basic Map Math
# Note: Adding/subtracting maps is possible if they share the same WCS
diff_map = aia_map_t2 - aia_map_t1

太阳坐标(sunpy.coordinates)

坐标系转换
from sunpy.coordinates import frames

# Helioprojective (Arcsec from Sun center)
coord = SkyCoord(100*u.arcsec, 200*u.arcsec, frame=frames.Helioprojective, 
                 obstime="2023-01-01", observer="earth")

# Convert to Heliographic Stonyhurst (Lat/Lon on the Sun)
hgs_coord = coord.transform_to(frames.HeliographicStonyhurst)
print(f"Lat: {hgs_coord.lat}, Lon: {hgs_coord.lon}")

# Rotating a coordinate with the Sun's differential rotation
from sunpy.physics.differential_rotation import solar_rotate_coordinate
new_coord = solar_rotate_coordinate(coord, time="2023-01-02")

数据搜索(sunpy.net.Fido)

复杂查询
from sunpy.net import Fido, attrs as a

# Search for GOES X-ray flares AND AIA images simultaneously
query = Fido.search(
    a.Time("2012-08-31 19:00", "2012-08-31 20:00"),
    (a.Instrument.goes & a.XRayRange("low")) | 
    (a.Instrument.aia & a.Wavelength(171 * u.AA))
)

print(query)
# files = Fido.fetch(query)

TimeSeries(sunpy.timeseries)

处理光变曲线
import sunpy.timeseries as ts

# Load GOES data
goes = ts.TimeSeries("goes_data.nc")

# Plotting
goes.peek()

# Export to Pandas
df = goes.to_dataframe()
# Perform rolling mean in pandas
df_smooth = df.rolling('1min').mean()

太阳物理算法

边缘拟合和表面数学
# Finding the solar limb in an image
from sunpy.map.maputils import all_coordinates_is_on_disk

# Mask pixels off-disk
mask = all_coordinates_is_on_disk(aia_map)
aia_map_masked = sunpy.map.Map(aia_map.data * mask, aia_map.meta)

实用工作流

1. 叠加 AIA 和 HMI(多仪器分析)
def plot_overlay(aia_file, hmi_file):
    aia = sunpy.map.Map(aia_file)
    hmi = sunpy.map.Map(hmi_file)
    
    # Re-project HMI to AIA's viewpoint
    hmi_reprojected = hmi.reproject_to(aia.wcs)
    
    fig = plt.figure()
    ax = fig.add_subplot(projection=aia)
    aia.plot(ax=ax)
    # Draw HMI contours (magnetic fields) over AIA (hot plasma)
    hmi_reprojected.draw_contours(ax=ax, levels=[-100, 100]*u.G, colors='white')
2. 测量耀斑通量变化
def get_flare_evolution(timeseries_file):
    goes = ts.TimeSeries(timeseries_file)
    # Filter for the X-ray flare window
    flare_data = goes.truncate("2017-09-06 11:50", "2017-09-06 12:30")
    
    # Get peak time and flux
    peak_time = flare_data.to_dataframe()['xrsa'].idxmax()
    return peak_time, flare_data.max()
3. 校正图像序列的差动自转
def rotate_map_series(maps, reference_time):
    rotated_maps = []
    for m in maps:
        # Rotate each map to the reference time
        m_rot = m.rotate(reproject=True, order=3) # Basic rotation
        # For actual solar surface rotation, use differential_rotation modules
        rotated_maps.append(m_rot)
    return rotated_maps

性能优化

预览时进行降采样

大型 AIA 图像(4096x4096)绘图速度较慢。

# Create a lower resolution map for fast display
aia_resampled = aia_map.resample([512, 512] * u.pix)
并行下载

Fido.fetch 可以使用多个连接来加快下载速度。

files = Fido.fetch(result, path='./data/', max_conn=5)

常见问题与解决方案

“缺少观测者”错误

由于 SunPy 不知道卫星的位置,计算会失败。

# ❌ Problem: SkyCoord transformation fails
# ✅ Solution: Manually set observer if missing in FITS header
from sunpy.coordinates import get_body_heliographic_stonyhurst
obs_coord = get_body_heliographic_stonyhurst('earth', aia_map.date)
aia_map.meta['hgln_obs'] = obs_coord.lon.value
aia_map.meta['hglt_obs'] = obs_coord.lat.value
aia_map.meta['dsun_obs'] = obs_coord.radius.to(u.m).value
方向问题(北方并非朝上)

太阳望远镜会旋转。

# ❌ Problem: Solar North is tilted in the raw image
# ✅ Solution: Rotate to align Solar North with the Y-axis
aia_rotated = aia_map.rotate() # This aligns the CROTA or PCi_j matrix
搜索结果为空

如果提供方不可用,Fido 可能不会返回任何结果。

# ✅ Solution: Always check result length
result = Fido.search(...)
if len(result) == 0:
    raise ValueError("No data found for the given criteria.")

SunPy 是探索离我们最近的恒星动态的权威工具包。通过整合物理单位和太阳专用坐标系,它能够支持稳健且可复现的日球层物理研究。

评论

支持 Markdown