Hinode/EIS Level-0 Spectra Visualization
Hinode/EIS Level-0 Spectra Visualization
Hinode EUV Imaging Spectrometer (EIS) Level-0 data contain raw EUV spectra of the solar corona
across multiple emission line windows (2006–present).
Each file covers one raster observation and stores spectra from up to ~25 emission lines
as a binary table in gzip-compressed FITS format.
The dataset page is at DARTS.
Data Files
Files are organized by observation date under:
https://data.darts.isas.jaxa.jp/pub/hinode/eis/level0/{YYYY}/{MM}/{DD}/
Each file covers one raster sequence:
eis_l0_{YYYYMMDD}_{HHMMSS}.fits.gz
The FITS file contains a Primary HDU (metadata only) and a DATA binary table extension.
Each row in the table corresponds to one slit position in the raster (NEXP rows total).
Spectral windows are stored as 2D arrays [n_wavelength × n_spatial] per row.
Key Primary HDU header keywords
| Keyword | Example value | Description |
|---|---|---|
DATE_OBS |
2017-10-12T06:13:19 |
Observation start time (UTC) |
DATE_END |
2017-10-12T06:16:15 |
Observation end time (UTC) |
XCEN |
-203.9 |
FOV center Solar-X (arcsec) |
YCEN |
43.1 |
FOV center Solar-Y (arcsec) |
FOVX |
479.2 |
Field of view in X (arcsec) |
FOVY |
488.0 |
Field of view in Y (arcsec) |
SLIT_ID |
40" |
Slit/slot width |
NWIN |
10 |
Number of spectral windows |
NEXP |
15 |
Number of raster slit positions |
OBSTITLE |
HOP323 (plage) |
Observation title |
TARGET |
Active Region |
Observation target |
DATA_LEV |
0 |
Processing level |
Binary table columns (DATA extension)
Each spectral window column is named after the emission line (e.g., Fe XII 195.120)
and has shape (n_wavelength, n_spatial) — typically (40, 488) pixels.
Additional scalar columns per row include:
| Column | Description |
|---|---|
TI_1 |
Exposure start time (seconds from DATE_OBS) |
exp_dur |
Exposure duration (seconds) |
XCEN_TI1 |
Solar-X center at exposure start (arcsec) |
YCEN_TI1 |
Solar-Y center at exposure start (arcsec) |
fmirr |
Fine mirror position (scan step) |
Visualization with Python
Requirements
pip install astropy matplotlib numpy requests
Helper functions
import re
import gzip
import io
import requests
import numpy as np
import matplotlib.pyplot as plt
from astropy.io import fits
BASE = "https://data.darts.isas.jaxa.jp/pub/hinode/eis/level0"
def list_eis_files(year, month, day):
"""Return list of file URLs for a given date."""
date_url = f"{BASE}/{year:04d}/{month:02d}/{day:02d}/"
resp = requests.get(date_url, timeout=30, verify=False)
if resp.status_code != 200:
return []
names = re.findall(r'href="(eis_l0_\w+\.fits\.gz)"', resp.text)
return [date_url + n for n in names]
def load_eis(url):
"""Download and open a gzip-compressed EIS Level-0 FITS file."""
r = requests.get(url, timeout=120, verify=False)
r.raise_for_status()
return fits.open(io.BytesIO(gzip.decompress(r.content)))
Example 1: List spectral windows and print observation summary
urls = list_eis_files(2017, 10, 12)
print(f"{len(urls)} files found")
with load_eis(urls[0]) as hdul:
h = hdul[0].header
print(f"Date: {h['DATE_OBS']} → {h['DATE_END']}")
print(f"Title: {h['OBSTITLE']}")
print(f"Target: {h['TARGET']}")
print(f"Center: ({h['XCEN']:.1f}\", {h['YCEN']:.1f}\")")
print(f"FOV: {h['FOVX']:.1f}\" × {h['FOVY']:.1f}\"")
print(f"Slit: {h['SLIT_ID']} | {h['NEXP']} raster positions")
print()
print("Spectral windows:")
for col in hdul[1].columns:
if col.dim: # spectral windows have dim set
print(f" {col.name:25s} shape={col.dim}")
Example 2: Plot a spectrum for one emission line at one slit position
with load_eis(urls[0]) as hdul:
h = hdul[0].header
data = hdul[1].data
spec_cols = [col.name for col in hdul[1].columns if col.dim]
# Pick the first available Fe XII window (name varies slightly between obs)
line = next((c for c in spec_cols if "Fe XII" in c), spec_cols[0])
cube = np.array([row[line] for row in data]) # shape: (NEXP, n_wave, n_spatial)
# Mean spectrum averaged over all slit positions and spatial pixels
mean_spec = cube.mean(axis=(0, 2))
fig, ax = plt.subplots(figsize=(8, 4))
ax.plot(mean_spec)
ax.set_xlabel("Wavelength pixel")
ax.set_ylabel("Intensity (raw counts)")
ax.set_title(f"Hinode/EIS {line} — {h['DATE_OBS'][:19]}")
plt.tight_layout()
plt.savefig("hinode_eis_spectrum.png", dpi=150, bbox_inches="tight")
plt.close()
Example 3: Build a spatial intensity map (sum over wavelength)
with load_eis(urls[0]) as hdul:
h = hdul[0].header
data = hdul[1].data
spec_cols = [col.name for col in hdul[1].columns if col.dim]
line = next((c for c in spec_cols if "Fe XII" in c), spec_cols[0])
cube = np.array([row[line] for row in data]) # (NEXP, n_wave, n_spatial)
# Integrate over wavelength axis → (NEXP, n_spatial) = (scan, slit)
intensity_map = cube.sum(axis=1).T # (n_spatial, NEXP)
fig, ax = plt.subplots(figsize=(6, 8))
vmin, vmax = np.percentile(intensity_map, [1, 99])
im = ax.imshow(intensity_map, origin="lower", cmap="hot",
vmin=vmin, vmax=vmax, aspect="auto")
fig.colorbar(im, ax=ax, label="Intensity (raw counts)")
ax.set_xlabel("Raster position (slit step)")
ax.set_ylabel("Spatial pixel (along slit)")
ax.set_title(f"Hinode/EIS {line}\n{h['DATE_OBS'][:19]}")
plt.tight_layout()
plt.savefig("hinode_eis_map.png", dpi=150, bbox_inches="tight")
plt.close()
Example 4: Compare multiple emission lines side by side
with load_eis(urls[0]) as hdul:
h = hdul[0].header
data = hdul[1].data
spec_cols = [col.name for col in hdul[1].columns if col.dim]
n = len(spec_cols)
fig, axes = plt.subplots(2, (n + 1) // 2, figsize=(14, 6))
for ax, line in zip(axes.flat, spec_cols):
cube = np.array([row[line] for row in data])
imap = cube.sum(axis=1).T
vmin, vmax = np.percentile(imap, [1, 99])
ax.imshow(imap, origin="lower", cmap="hot", vmin=vmin, vmax=vmax, aspect="auto")
ax.set_title(line, fontsize=8)
ax.set_axis_off()
for ax in axes.flat[n:]:
ax.set_visible(False)
fig.suptitle(f"Hinode/EIS — {h['DATE_OBS'][:19]}")
plt.tight_layout()
plt.savefig("hinode_eis_all_lines.png", dpi=150, bbox_inches="tight")
plt.close()
Notes
- Level-0 data are raw telemetry with no radiometric calibration. For calibrated spectra (Level-1), use the IDL
eis_preproutine from Solar Software (SSW) or the Python packageeispac. - The spectral window names in the binary table correspond to the dominant emission line in each window. Each window contains
n_wavelengthspectral pixels (typically 24–40) ×n_spatialslit pixels (up to 512). - The
SLIT_IDkeyword identifies the slit used:1",2",40"(slot), or266"(slot). The 40" and 266" slots produce context images rather than true spectra. - SSL certificate verification may fail for
data.darts.isas.jaxa.jp; passverify=Falsetorequests.getas a workaround. - For absolute wavelength calibration, a dispersion of approximately 0.0223 Å/pixel applies to the short-wavelength channel (SW: 170–210 Å) and 0.0446 Å/pixel to the long-wavelength channel (LW: 250–290 Å).
Acknowledgement
When using this data in publications, please follow the Hinode data use guidelines and cite:
- Kosugi, T. et al. (2007), Sol. Phys., 243, 3. doi:10.1007/s11207-007-9014-6 — Hinode mission
- Culhane, J.L. et al. (2007), Sol. Phys., 243, 19. doi:10.1007/s11207-007-9996-1 — EIS instrument