Skip to main content

license: mit task_categories:

  • image-to-image
  • time-series-forecasting tags:
  • solar
  • heliophysics
  • astronomy
  • AIA
  • SDO
  • EUV
  • SXR
  • GOES
  • flare
  • space-weather pretty_name: "FOXES: Framework for Operational X-ray Emission Synthesis" size_categories:
  • 100K<n<1M language:
  • en datasets:
  • griffingoodwin04/FOXES-Data

FOXES: Framework for Operational X-ray Emission Synthesis

FOXES Logo

FOXES predicts full-disk solar soft X-ray (SXR) flux and spatial patch contributions from seven-channel SDO/AIA extreme-ultraviolet images. This repository contains the Python API, data tools, training code, and evaluation workflows developed through Frontier Development Lab's Heliolab 2025.

Model Demo · Dataset · Notebook Walkthrough

API overview

Import the public API with import helio_foxes. The examples below use processor for an ObservationProcessor, model for a Predictor, result for a Prediction, and series for a PredictionSeries. See the Python API guide for usage examples, or the complete API reference for parameter descriptions, return values, and every keyword default, rendered from the source docstrings. * marks keyword-only arguments. The source links below open each definition in helio_foxes/api.py.

Function or method What it does Source
load_model(checkpoint_path, *, device='auto', aia_norm_path=None) Load a checkpoint and return a reusable Predictor. · Docs load_model
predict(image, *, model, timestamp=None) / Predictor.predict(image, *, timestamp=None) Predict from an Observation or a processed AIA array. · Docs · Docs predict, Predictor.predict
ObservationProcessor.fetch_observation(date, *, include_aia=None, include_harps=None, include_sxr=None) -> Observation Fetch and preprocess AIA with optional HARP regions and measured GOES flux. · Docs ObservationProcessor.fetch_observation
ObservationProcessor.iter_observations(start, end, *, cadence='1h', on_error='raise', save_dir=None, overwrite=False, progress=False, **kwargs) Yield observations over a time range; use save_dir to save and reuse processed observations. · Docs ObservationProcessor.iter_observations
Predictor.predict_series(observations, *, snapshot_time=None, snapshot_wavelength=193) Predict a sequence and return a PredictionSeries; optionally retain an AIA snapshot. · Docs Predictor.predict_series
plot_flux_map(prediction, *, ax=None, cmap='inferno', vmin=None, vmax=None, show_harp_boxes=False, harp_regions=None, timestamp=None, jsoc_email=None, min_harp_flux=1e-07, harp_label_fontsize=6, show_harp_uncertainty=True, harp_label_offsets=None, harp_label_max_shift=80, aia_image=None, harp_colors=None) Plot patch flux contributions, with optional HARP boxes. · Docs plot_flux_map
plot_uncertainty_map(prediction, *, ax=None, cmap='magma', vmin=None, vmax=None) Plot Gaussian patch variance attribution when available. · Docs plot_uncertainty_map
PredictionSeries.plot(*, harpnums=None, ax=None, include_full_disk=False, include_sxr=False, show_snapshot=False, snapshot_ax=None, aia_ax=None, show_uncertainty=True, min_peak_flux=0.0, legend='auto') Plot HARP light curves, with optional full-disk prediction, GOES comparison, and snapshot panels. · Docs PredictionSeries.plot
PredictionSeries.to_dataframe() Return full-disk predictions and measured XRS-B flux indexed by UTC time. · Docs PredictionSeries.to_dataframe
PredictionSeries.harp_light_curves() Return a dictionary of HARP numbers and regional light-curve DataFrames. · Docs PredictionSeries.harp_light_curves
Observation.from_array(data, *, timestamp, wavelengths=(94, 131, 171, 193, 211, 304, 335), padding_factor=0.1, harp_regions=None, sxr=None) Wrap your processed AIA array and its metadata as an observation. · Docs Observation.from_array
Observation.from_npy(path, *, timestamp, **kwargs) Create an observation from a processed .npy stack. · Docs Observation.from_npy
Observation.save(path, *, overwrite=False) / Observation.load(path) Save or restore one complete observation as a .npz archive. · Docs · Docs Observation.save, Observation.load
load_observations(directory, *, progress=False) Lazily load saved .npz observations for reuse. · Docs load_observations
parse_timestamp(value) Convert supported timestamp formats to a UTC datetime. · Docs parse_timestamp

For individual data sources, use AIAProcessor.fetch_date(date), HARPProcessor.fetch_date(date), or SXRProcessor.fetch_date(date) on an instance of the corresponding helio_foxes class. AIAProcessor.process_files(paths) processes local AIA FITS files.

The public data classes are ObservationMetadata, Observation, Prediction, and PredictionSeries. A prediction exposes flux, flux_map, harp_regions, sxr, intervals, and patch_uncertainty_map. Gaussian uncertainty fields are None for deterministic checkpoints.

Processor and predictor constructors

ObservationProcessor(*, email=None, resolution=512, tolerance=120, n_workers=4, aia_norm_path=None, include_aia=True, include_harps=True, harp_bbox_expansion=0.0, include_sxr=True, sxr_tolerance=120, sxr_satellite=None)
AIAProcessor(*, email=None, resolution=512, tolerance=120, n_workers=4, aia_norm_path=None)
HARPProcessor(*, email=None, resolution=512, padding_factor=0.1, bbox_expansion=0.0)
SXRProcessor(*, tolerance=120, satellite=None)
Predictor(checkpoint_path, *, device='auto', aia_norm_path=None)

iter_observations(..., **kwargs) forwards include_aia, include_harps, and include_sxr to fetch_observation. Observation.from_npy(..., **kwargs) accepts the wavelengths, padding_factor, harp_regions, and sxr options from Observation.from_array. See the complete reference for their meanings.

Discover functions and arguments interactively

import inspect
import helio_foxes

print(helio_foxes.__all__)  # Names exported by the public API.
print(inspect.signature(helio_foxes.load_model))  # Arguments and defaults.
help(helio_foxes.ObservationProcessor.fetch_observation)  # Detailed documentation.
help(helio_foxes.Prediction)  # Returned fields and their meanings.

In Jupyter, type helio_foxes. and press Tab to browse names, or run helio_foxes.load_model? to see its documentation. Use help(helio_foxes.PredictionSeries.plot) to inspect all light-curve plot options.

Install

From a local checkout:

python -m pip install -e .

The package is named helio-foxes; import it as helio_foxes. For a fresh environment, editable tests, or notebook kernel setup, follow the development setup.

Predict one observation

The examples below use the same timestamps, checkpoints, and plotting settings as the saved outputs in the heliofoxes notebook. Use a registered JSOC email and download the checkpoints below. Load the model once and reuse it for each observation.

Download checkpoints

The single-observation and time-range examples use Complex Gaussian. Download the other two checkpoints to run the comparison example. Save each file at the path shown, relative to the directory where you run the code. These downloads are separate from the PyPI package.

Model Download Save as
Complex Gaussian ComplexModel.ckpt forecasting/trained_weights_and_normalization/updated_architecture_checkpoints/ComplexModel.ckpt
Lighter Gaussian SlightlyLighterModel.ckpt forecasting/trained_weights_and_normalization/updated_architecture_checkpoints/SlightlyLighterModel.ckpt
Deterministic inverted-attention-mask.ckpt forecasting/trained_weights_and_normalization/inverted-attention-mask.ckpt

Load the model and predict

from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
import helio_foxes

weights = Path("forecasting/trained_weights_and_normalization")
model = helio_foxes.load_model(
    weights / "updated_architecture_checkpoints" / "ComplexModel.ckpt",
    device="auto",
)
processor = helio_foxes.ObservationProcessor(
    email="you@example.com", harp_bbox_expansion=0.2,
)
observation = processor.fetch_observation("2023-07-11T01:30:00Z")
result = model.predict(observation)

print(f"Predicted XRS-B: {result.flux:.3e} W/m²")
if observation.sxr is not None:
    print(f"Measured XRS-B: {observation.sxr['xrsb_flux']:.3e} W/m²")

fig, ax = plt.subplots(figsize=(10, 7))
helio_foxes.plot_flux_map(
    result, ax=ax, show_harp_boxes=True, min_harp_flux=1e-7,
)
plt.show()

Saved notebook output for 2023-07-11 at 01:30 UTC:

Predicted XRS-B: 2.695e-06 W/m²
Measured XRS-B: 2.941e-06 W/m²

Complex Gaussian patch flux map with HARP active-region boxes for 2023-07-11 at 01:30 UTC

Inspect the AIA inputs

Plot the seven processed channels from the same observation:

fig, axes = plt.subplots(2, 4, figsize=(14, 7), constrained_layout=True)
for ax, wavelength, image in zip(
    axes.flat, observation.metadata.wavelengths, observation.data,
):
    low, high = np.percentile(image, [1, 99])
    ax.imshow(image, origin="lower", cmap="gray", vmin=low, vmax=high)
    ax.set_title(f"AIA {wavelength} Å")
    ax.axis("off")
for ax in axes.flat[len(observation.metadata.wavelengths):]:
    ax.axis("off")
plt.show()

Seven processed AIA input channels for 2023-07-11 at 01:30 UTC

Compare checkpoints

Reuse the same observation to compare the three notebook checkpoints:

checkpoints = {
    "Complex Gaussian": weights / "updated_architecture_checkpoints" / "ComplexModel.ckpt",
    "Lighter Gaussian": weights / "updated_architecture_checkpoints" / "SlightlyLighterModel.ckpt",
    "Deterministic": weights / "inverted-attention-mask.ckpt",
}
for name, checkpoint in checkpoints.items():
    predictor = helio_foxes.load_model(checkpoint, device="auto")
    prediction = predictor.predict(observation)
    print(f"{name}: {prediction.flux:.3e} W/m²")
    del predictor
Checkpoint Saved prediction (W/m²)
Complex Gaussian 2.695 × 10⁻⁶
Lighter Gaussian 2.947 × 10⁻⁶
Deterministic 2.899 × 10⁻⁶

The measured GOES XRS-B flux at the same time is 2.941 × 10⁻⁶ W/m², using GOES-16 and GOES-18. These are individual notebook examples.

Fetching downloads and preprocesses AIA data and obtains supplementary HARP regions and GOES measurements. Raw downloads are temporary. Missing HARP or GOES data do not discard a usable AIA observation.

Already have data? See loading your own processed arrays or local FITS files. Inputs must match the checkpoint's training preprocessing and wavelength order: [94, 131, 171, 193, 211, 304, 335] Å.

Predict a time range

observations = processor.iter_observations(
    "2024-03-23 00:45", "2024-03-23 02:45",
    cadence="1min", progress=True, save_dir="saved_observations",
    on_error="skip",
)
series = model.predict_series(
    observations, snapshot_time="2024-03-23 01:45", snapshot_wavelength=193,
)
ax = series.plot(
    show_snapshot=True, show_uncertainty=True, min_peak_flux=1e-7, legend="auto",
)
plt.show()

totals = series.to_dataframe()
harp_curves = series.harp_light_curves()  # {HARP number: DataFrame}

Using the Complex Gaussian model loaded above, the saved notebook run produced 121 predictions. The flux-map and AIA panels show the retained snapshot at 2024-03-23 01:45 UTC.

HARP light curves from 2024-03-23 00:45 to 02:45 UTC alongside the flux map and AIA 193 angstrom snapshot at 01:45 UTC

*Shading and regional ± values show the model's variance attribution; they are not calibrated yet.

The iterator downloads and preprocesses observations one at a time. Existing saved files are reused, so rerunning a range skips completed downloads and preprocessing. AIA record selection uses a bulk JSOC query.

snapshot_time keeps the nearest observation's AIA channel for the flux-map and image panels. Omit it to retain no image; use series.plot() for curves only. Gaussian models show uncertainty when available; deterministic models do not.

Reload saved observations without downloading or preprocessing again:

saved = helio_foxes.load_observations("saved_observations")
series = model.predict_series(saved)
series.plot()

See the API guide for timestamp formats, cadence, source toggles, snapshot selection, uncertainty, plot controls, and saved data.

Models and documentation

The repository includes the original deterministic models and newer local + global Gaussian checkpoints. The newer checkpoints have not yet been validated for prediction quality, spatial maps, or uncertainty calibration. Patch and HARP uncertainties attribute global model variance; they are not calibrated local error bars.

After editing installed source, restart an existing notebook kernel and rerun the setup cell so it loads the current API.

Citation

If you use this code or data in your work, please cite:

@software{FOXES,
    title           = {{FOXES: A Framework For Operational X-ray Emission Synthesis}},
    institution     = {Frontier Development Lab (FDL)},
    repository-code = {https://github.com/griffin-goodwin/FOXES},
    version         = {v1.0},
    year            = {2026}
}

Acknowledgement

This work is a research product of Heliolab (heliolab.ai), an initiative of the Frontier Development Lab (FDL.ai). FDL is a public–private partnership between NASA, Trillium Technologies (trillium.tech), and commercial AI partners including Google Cloud and NVIDIA. Heliolab was designed, delivered, and managed by Trillium Technologies Inc., a research and development company focused on intelligent systems and collaborative communities for Heliophysics, planetary stewardship and space exploration. We gratefully acknowledge Google Cloud for extensive computational resources and NVIDIA Corporation. This material is based upon work supported by NASA under award number No. 80GSFC23CA040. Any opinions, findings, conclusions or recommendations expressed are those of the authors and do not necessarily reflect the views of the National Aeronautics and Space Administration.

Large language models were used as brainstorming tools to discuss possible training strategies and methodological considerations. The authors retained full responsibility for all research decisions, interpretations, and conclusions presented in this work.

Metadata

Release files for helio-foxes 1.0.7

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for helio-foxes 1.0.7
File Size Uploaded Provenance Actions
helio_foxes-1.0.7.tar.gz 151.5 kB With provenance Details for helio_foxes-1.0.7.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for helio-foxes 1.0.7
File Interpreter ABI Platform Actions
helio_foxes-1.0.7-py3-none-any.whl Python 3 none any Details for helio_foxes-1.0.7-py3-none-any.whl

Total release size: 280.2 kB

Release files / helio_foxes-1.0.7.tar.gz

Download URL helio_foxes-1.0.7.tar.gz
Size 151.5 kB
Tags Source
SHA-256 checksum
How to use checksums
d222b45ba528f3528ee16c504f84197d9cb42ca3b75cde1e9dee0c9ca063f000
BLAKE2b-256 checksum
How to use checksums
db8e048d015dbd6ca2271892ef63f73f9320de697a214f301d06be7426b67d23
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

Release files / helio_foxes-1.0.7-py3-none-any.whl

Download URL helio_foxes-1.0.7-py3-none-any.whl
Size 128.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
92ca913fc70afa5a1ff5ba5ead2cb99ddfc4a6bd55223021355824685ffe6482
BLAKE2b-256 checksum
How to use checksums
ebd49d1aa266f3c3f50c39b775f8bcb13f00c853a01947a32034342a4a8de86f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

Security for helio-foxes 1.0.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for helio_foxes-1.0.7.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page