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: A Framework For Operational X-ray Emission Synthesis
This repository contains the code and resources for FOXES, a project developed as part of the Frontier Development Lab's Heliolab 2025!
Model / Data:
https://huggingface.co/spaces/griffingoodwin04/FOXES-model
https://huggingface.co/datasets/griffingoodwin04/FOXES-Data
Original FOXES abstract
The solar soft X-ray (SXR) irradiance is a long-standing proxy of solar activity, used for the classification of flare strength. As a result, the flare class, along with the SXR light curve, are routinely used as the primary input to many forecasting methods, from coronal mass ejection speed to energetic particle output. However, the SXR irradiance lacks spatial information leading to dubious classification during periods of high activity, and is applicable only for observations from Earth orbit, hindering forecasting for other places in the heliosphere. This work introduces the Framework for Operational X-ray Emission Synthesis (FOXES), a Vision Transformer-based approach for translating Extreme Ultraviolet (EUV) spatially-resolved observations into SXR irradiance predictions. The model produces two outputs: (1) a global SXR flux prediction and (2) per-patch flux contributions, which offer a spatially resolved interpretation of where the model attributes SXR emission. This paves the way for EUV-based flare detection to be extended beyond Earth's line of sight, allowing for a more comprehensive and reliable flare catalog to support robust, scalable, and real-time forecasting, extending our monitoring into a true multiviewpoint system.
Team: Griffin Goodwin, Alison March, Jayant Biradar, Christopher Schirninger, Robert Jarolim, Angelos Vourlidas, Viacheslav Sadykov, Lorien Pratt
The Original FOXES Model
The original model predicts a raw SXR flux contribution for each image patch.
Its three trained checkpoints use global, local, or inverted
attention. The model converts patch logits to flux and clamps very small
contributions to a positive floor (1e-15 W/m²), which can make the maps
relatively sparse. In the evaluations run so far, global RMSE and MSE were
good, but the spatial maps for weak flares and quiet-Sun images were less
convincing. This motivated the updated model below.
The Updated (Post Publication) FOXES Model: Local + Global Context
The maintained model in this repository extends the released FOXES patch predictor. Local attention builds a feature for each AIA image patch. Patch flux starts from a positive, image-wide baseline divided across the patches; each patch's output scales its share. A global query then summarizes the full AIA image and uses that context, together with each patch's local features, to adjust its flux contribution. The corrected patch fluxes sum to the full-disk SXR prediction.
This local + global design produces less sparse, visually better spatial flux maps in the examples examined so far. It also predicts a global Gaussian uncertainty and a map of each patch's contribution to that variance. The uncertainty map is an attribution of global uncertainty; there are no patch-level SXR labels to establish calibrated local error bars.
The tradeoff is somewhat worse global SXR prediction performance than the original released FOXES model in the evaluations run so far. The visual map improvement is qualitative. The newly added local + global checkpoints listed below have not yet been validated; these earlier observations should not be read as evaluation results for either new checkpoint file.
Repository Structure
This repository covers the full loop: getting data, training, running inference, and evaluating a FOXES model.
FOXES
├── download
│ ├── hugging_face_data_download.py # Recommended: HF Hub -> .npy (streamed, or from local parquet)
│ ├── hf_download_config.yaml # Config for hugging_face_data_download.py
│ ├── download_sdo.py # Advanced: raw AIA download from JSOC (needs data/build_dataset.py after)
│ ├── sdo_download_config.yaml # Config for download_sdo.py
│ ├── download_sxr.py # Advanced: raw GOES SXR download via SunPy Fido (needs data/build_dataset.py after)
│ └── sxr_download_config.yaml # Config for download_sxr.py
├── data
│ ├── build_dataset.py # Runs the full raw -> processed pipeline below in one command
│ ├── build_dataset_config.yaml # Config for build_dataset.py
│ ├── clean_aia.py # Drop AIA FITS files with a bad DATE-OBS timestamp
│ ├── convert_aia.py # Raw AIA FITS -> paired 512x512 .npy stacks (itipy)
│ ├── combine_sxr.py # Combine raw multi-satellite GOES files into per-satellite CSVs
│ ├── align_aia_sxr.py # Match AIA timestamps to GOES CSVs -> per-timestamp SXR .npy
│ ├── split_train_val_test.py # Split processed AIA/SXR into train/val/test (use for training a new model only)
│ └── sxr_normalization.py # Compute log-space mean/std over SXR .npy files for training
├── forecasting
│ ├── dataset.py # AIAGOESDataset / AIAGOESDataModule: loads paired AIA + SXR .npy files
│ ├── model.py # Released deterministic and current local + global Gaussian models
│ ├── inference.py # Run a checkpoint over a folder of data; writes predictions.csv
│ ├── inference_config.yaml # Config for inference.py
│ ├── evaluation.py # Compute metrics and generate evaluation plots
│ ├── evaluation_config.yaml # Config for evaluation.py
│ └── trained_weights_and_normalization/ # Tracked original weights; local newer weights may also be staged here
├── training
│ ├── train.py # Train released deterministic or current local + global model
│ ├── train_config.yaml # Points to the maintained coupled Gaussian config
│ ├── train_coupled_gaussian.yaml
│ ├── train_deterministic.yaml
│ └── callbacks.py # W&B prediction, attention, and spatial-map callbacks
└── requirements.txt # Python dependencies
Setup
Use FOXES from a Python UI
Install this checkout in the UI environment:
pip install -e .
Load a checkpoint once when the UI starts, then reuse it for each image:
import helio_foxes
model = helio_foxes.load_model("/path/to/model.ckpt", device="auto")
processor = helio_foxes.ObservationProcessor(email="you@example.com")
observation = processor.fetch_observation("2023-08-01T00:00:00Z")
print(observation.data.shape) # (7, 512, 512)
result = helio_foxes.predict(observation, model=model)
print(result.flux) # full-disk SXR flux, W/m²
print(result.flux_map) # patch contributions, W/m²
print(result.harp_regions) # HARP numbers, locations, and flux sums, W/m²
print(result.sxr) # measured GOES XRS-A/XRS-B fluxes and sample time
ax = helio_foxes.plot_flux_map(result) # optional: vmin=1e-10, vmax=1e-6
ax.figure.savefig("flux_map.png")
When plotting a prediction, the title automatically shows the predicted FOXES
flux and the observed SXR-B mean when available, in W/m². For Gaussian models,
it also shows the model's full-disk uncertainty beside the predicted flux as
± value, computed as the square root of the summed patch variances. This is
a model estimate, not a calibrated error bar.
ObservationProcessor calls AIAProcessor, HARPProcessor, and SXRProcessor
for the same requested timestamp. All three sources are fetched by default.
AIA and HARPs share the crop geometry and JSOC email; GOES SXR needs no email.
Prediction adds a flux_sum in W/m² and a canonical lowercase harpnum to
each region in result.harp_regions. Each result includes top_pct,
left_pct, width_pct, and height_pct for its location in the image.
Original JSOC fields, including LON_MIN, LON_MAX, LAT_MIN, and LAT_MAX,
are preserved. The observation's queried rows are not modified.
for harp in result.harp_regions or []:
print(harp["harpnum"], harp["flux_sum"], "W/m²")
Plotting reuses these regions and the same flux summation rule:
ax = helio_foxes.plot_flux_map(result, show_harp_boxes=True)
For Gaussian models, each HARP result also contains flux_sum_uncertainty
in W/m²: square the patch uncertainties, sum within the same box as the flux,
then take the square root. Empty boxes have zero uncertainty; deterministic
models return None. These values follow the model's additive variance
attribution; they have not been calibrated as regional error bars.
Uncertainty appears on a third label line as ± value when available.
Hide it with show_harp_uncertainty=False:
ax = helio_foxes.plot_flux_map(result, show_harp_boxes=True, show_harp_uncertainty=False)
for harp in result.harp_regions or []:
print(harp["harpnum"], harp["flux_sum"], harp["flux_sum_uncertainty"])
Each HARP box is labeled with its number and flux sum in W/m². Labels use a
fixed font size; set harp_label_fontsize to change it. A standard
Matplotlib annotation places each label diagonally outside a box corner with
a three-point gap in both x and y. The entire label extends outward from
the corner. The side
toward the image center is preferred. A simple overlap pass tries the other
corners before four-point nudges, keeping automatic positions outside their
HARP box and inside the map. Shifted
labels get connector lines. harp_label_max_shift=80 limits movement to 80
points from a corner; lower it to keep labels closer, or set it
to zero for labels fixed at their preferred corner. If no free position is found within the limit, the
label stays at its starting position. Crowded cases may need manual offsets
or a higher min_harp_flux. Labels are not automatically hidden. This runs
once when plotting; replot after substantial size changes.
For crowded maps, set individual labels' starting positions. Offsets are in points from the chosen corner: positive x moves right, positive y moves up. Manually offset labels get matching connector lines:
ax = helio_foxes.plot_flux_map(
result, show_harp_boxes=True,
harp_label_offsets={1234: (15, 30), 5678: (-20, -30)},
)
Box outlines and labels share a fixed color by flux rank (strongest: sky blue, second: orange, third: green).
Expand HARP boxes when fetching observations so prediction sums and plot outlines use the same expanded region:
processor = helio_foxes.ObservationProcessor(email=email, harp_bbox_expansion=0.1)
observation = processor.fetch_observation(timestamp)
result = helio_foxes.predict(observation, model=model)
harp_bbox_expansion defaults to zero. 0.1 adds 10% of each box's width and
height on each side (20% more total width and height), clipped to the image.
Original JSOC heliographic bounds are preserved. For direct HARP queries, use
helio_foxes.HARPProcessor(email=email, bbox_expansion=0.1). The expansion is carried
in observation metadata for HARP queries deferred until plotting.
Set min_harp_flux to hide regions below an absolute flux sum in W/m²:
ax = helio_foxes.plot_flux_map(result, show_harp_boxes=True, min_harp_flux=1e-8)
The default threshold is 1e-7 W/m²; use min_harp_flux=0 to show all regions.
Filtering only affects the plot;
result.harp_regions retains all predicted regional sums.
Set include_aia=False, include_harps=False, or include_sxr=False on
ObservationProcessor to disable a source. Override any setting for one
observation with processor.fetch_observation(timestamp, include_sxr=False)
(and similarly for AIA/HARPs). With AIA disabled, observation.data is None,
and prediction requires fetching AIA first. Each component processor handles
only its own source.
If the observation did not fetch HARPs, plotting with show_harp_boxes=True
queries them using the prediction metadata and its jsoc_email argument.
Pass harp_regions=regions to the plot to use an explicit set of regions.
harp_regions=None means no query was requested; [] means no usable HARP
regions were returned, including query failures. Plotting reuses an empty
result without repeating the query. HARP data is supplementary, so an empty
HARP result does not discard the AIA observation.
observation.metadata is preserved as result.metadata. It records the
requested UTC timestamp, channel order, original processed image shape, and
crop padding. The timestamp is the requested time, not the individual AIA
exposure times. The JSOC email stays on the processor or plotting call.
For array-based workflows, helio_foxes.AIAProcessor(email=email).fetch_date(timestamp)
returns a NumPy stack. Supply its time once to helio_foxes.predict(image, model=model, timestamp=timestamp) to enable automatic HARP queries from the result. This
assumes the standard AIA channel order and crop padding of 0.1. For a different
crop, wrap the array in helio_foxes.Observation with explicit
helio_foxes.ObservationMetadata. Plotting a plain flux-map array also continues to
accept an explicit timestamp.
Each sum includes positive patch contributions whose centers fall inside the HARP box. Boxes can overlap, so their sums need not add to the full-disk flux.
Measured GOES SXR
The observation's sxr dict is also carried into result.sxr; it is a measured
comparison value and is not used as model input. XRS-B is the 1–8 Å band to
compare with the predicted result.flux; XRS-A is 0.5–4 Å. Fluxes are in W/m².
processor = helio_foxes.ObservationProcessor(
email="you@example.com", include_sxr=True, sxr_tolerance=120,
sxr_satellite=None, # optionally restrict to e.g. 18
)
observation = processor.fetch_observation("2023-08-01T00:00:00Z")
result = helio_foxes.predict(observation, model=model)
if result.sxr is not None:
print("Predicted:", result.flux, "Observed:", result.sxr["xrsb_flux"])
print(result.sxr["satellites"], result.sxr["timestamp"])
print(result.sxr["measurements"]) # individual contributing satellite values
print(result.sxr["time_offset_seconds"]) # sample minus requested UTC time
# Fetch just SXR, using the same datetime/ISO string format:
sxr = helio_foxes.SXRProcessor(tolerance=120, satellite=18).fetch_date(timestamp)
# Or through the observation fetcher:
sxr_only = processor.fetch_observation(timestamp, include_aia=False, include_harps=False)
SXRProcessor downloads the GOES science avg1m product and finds the nearest
usable timestamp within tolerance seconds (120 by default; time ties favor
the earlier sample). At that timestamp, xrsb_flux is the arithmetic mean of
available satellites' finite positive XRS-B values with zero XRS-B quality
flags. This follows data/align_aia_sxr.py: average in physical W/m² before
the training transform applies log normalization. result.flux also uses
physical W/m², so no normalization is needed for comparison.
satellites names the contributors and measurements retains their individual
values. Each satellite counts once; measurements at different timestamps are
never averaged together. Restricting satellite yields a single-satellite
result. XRS-A is averaged over valid short-band measurements from the XRS-B
contributors, or None if unavailable. Bad XRS-A values do not exclude good
XRS-B measurements from the model comparison. The returned timestamp is the
actual sample time, while observation.metadata.timestamp remains the requested
time. Daily files are filtered to the requested window and deleted after use.
No interpolation or additional legacy scaling is applied to the reprocessed
science fluxes. sxr=None means fetching was disabled or no usable measurement
was available, including network or processing failures; these failures log a
warning and do not discard the AIA observation. The science archive may lag
recent observations. Check the calibration used for older training datasets
before interpreting measured-versus-predicted differences. Unlike the bulk
dataset converter, this fetcher does not fill missing fluxes using log-space
interpolation; only valid measured samples contribute.
GOES netCDF reading requires h5netcdf and h5py, both declared package
dependencies. If an existing environment reports either missing, run
python -m pip install h5netcdf h5py using that environment's Python. In a
notebook, run %pip install h5netcdf h5py and restart the kernel.
To install:
python -m pip install -e .
AIAProcessor.fetch_date writes the seven raw AIA FITS frames to a temporary
directory, processes them with ITI, and returns the stack in memory.
ObservationProcessor.fetch_observation uses this same processing path. The raw files are
removed when the call finishes, including when a download is incomplete.
The requested timestamp is interpreted as UTC. An ISO string with an offset
is converted to UTC; a timestamp without an offset is assumed to be UTC.
If you provide aia_norm_path to AIAProcessor, do not also pass that
artifact to load_model, since that would normalize the stack twice.
The input uses channel order [94, 131, 171, 193, 211, 304, 335] and must
already have the same preprocessing as the checkpoint's training data. If that
training used an AIA normalization artifact, pass aia_norm_path to
helio_foxes.load_model. result.intervals and result.patch_uncertainty_map are
available for the coupled Gaussian model. Checkpoints are passed by path and
are not bundled into the Python package. Pass a path to a full checkpoint
file available on the UI machine.
1) Clone
git clone https://github.com/griffin-goodwin/FOXES.git
cd FOXES
2) Create an environment
Option A — pip:
conda create -n foxes python=3.14 -y
conda activate foxes
pip install -r requirements.txt
Running the Model
FOXES is run in four steps: get data, inference (run a checkpoint over your data), evaluation (score the predictions and generate plots), and optionally training your own model. All are driven by a YAML config — edit the config, then run the script.
The checked-in configs use paths relative to the repository root:
./foxes_data/ for downloaded or processed data and ./foxes_outputs/ for
predictions and plots. Run the commands below from the repository root, or
replace those paths with locations on your machine. For inference, set
data.checkpoint_path to a full checkpoint file available on your machine.
0) Get data
Recommended: stream the released dataset straight from Hugging Face Hub
into the paired .npy layout inference expects — no separate processing step:
python download/hugging_face_data_download.py --config download/hf_download_config.yaml
Edit download/hf_download_config.yaml first to set aia_dir/sxr_dir, which
splits to pull, and whether to subsample.
If you've already downloaded the HF parquet files locally instead of
streaming, set local_parquet_dir in that same config to the root folder
containing your per-split subdirs (train/, validation/ or val/, test/)
— streaming and the HF Hub login are skipped entirely in that case.
Advanced: to acquire and process raw data yourself instead, edit and run the two download configs, then the one dataset-build config, in order:
# 1) Raw AIA FITS from JSOC (requires a registered email)
python download/download_sdo.py --config download/sdo_download_config.yaml
# 2) Raw GOES XRS data via SunPy Fido
python download/download_sxr.py --config download/sxr_download_config.yaml
# 3) Clean + convert AIA, combine + align SXR -> paired .npy (see data/build_dataset_config.yaml)
python data/build_dataset.py --config data/build_dataset_config.yaml
data/build_dataset.py runs the full raw-to-processed pipeline in one command
(clean AIA → convert AIA → combine GOES → align AIA/SXR); each step can be
skipped via the steps: block in its config if you've already run it.
Inference/evaluation just need the flat output of that — training needs two
more things, both off by default and only relevant if you're training:
steps.split: true— splitsaia.processed_dir/output.sxr_dirintotrain//val//test/subfolders (date ranges or a month-based default; see thesplit:block in the config).sxr_normalization.compute: true— computes SXR normalization stats from the train split (requiressteps.splitto have run first).
To regenerate only the SXR normalization artifact for an existing split (the
training convention is log10(SXR + 1e-8)), run:
python data/sxr_normalization.py \
--sxr-dir /data/SXR_processed/train \
--output /data/SXR_processed/normalized_sxr.npy
1) Data format
Point inference.py at a folder of paired .npy files, one file per timestamp:
/your/aia_dir/
├── 2023-08-01T00:00:00.npy # (7, 512, 512) float32 — one channel per AIA wavelength
├── 2023-08-01T00:01:00.npy
└── ...
/your/sxr_dir/ # only needed if you have ground truth to compare against
├── 2023-08-01T00:00:00.npy # scalar xrsb_flux value
└── ...
Timestamps are matched by filename between aia_dir and sxr_dir — there's no
required subfolder name (no train/, val/, or test/). Just point the config
at whichever folder holds the data you want to run.
If you don't have ground-truth SXR data (e.g. scoring new/live data), set
prediction_only: "true" in the config and data.sxr_dir is ignored entirely.
2) Run inference
The three original released checkpoints are included under
forecasting/trained_weights_and_normalization/, differing only in the
self-attention mask they were trained with. Each checkpoint carries its own
mask, so switch between those original models with checkpoint_path:
| Checkpoint | mask_mode |
Description |
|---|---|---|
inverted-attention-mask.ckpt |
inverted |
Original released FOXES model. Each patch attends to distant patches (the flipped local-attention mask it was actually trained with). |
localized-attention-mask.ckpt |
local |
True local attention — the opposite of the original model: each patch attends only to its own neighborhood. |
no-attention-mask.ckpt |
none |
Global ViT — standard full/global attention, no masking at all. |
This working copy also has two newer local + global Gaussian checkpoint files
under updated_architecture_checkpoints/. Their
architecture and normalization details below come from the local checkpoint
metadata; neither has yet been validated for prediction quality, spatial
maps, or uncertainty calibration.
| Local checkpoint | Architecture recorded in checkpoint | Status |
|---|---|---|
updated_architecture_checkpoints/ComplexModel.ckpt |
12 layers, 8 attention heads, local mask, global patch adjustment | Local file; unvalidated; remote availability unconfirmed |
updated_architecture_checkpoints/SlightlyLighterModel.ckpt |
4 layers, 4 attention heads, local mask, global patch adjustment | Local file; unvalidated; remote availability unconfirmed |
Both newer checkpoints contain SXR normalization values matching the locally
staged updated_architecture_checkpoints/normalized_sxr_updated_FOXES.npy.
The original three checkpoints contain values matching the locally staged
normalized_sxr_FOXES_paper.npy instead.
Edit forecasting/inference_config.yaml:
data:
aia_dir: "/path/to/your/aia_data"
sxr_dir: "/path/to/your/sxr_data" # omit/ignore if prediction_only
sxr_norm_path: null # optional: set to the matching local normalization file
checkpoint_path: "forecasting/trained_weights_and_normalization/inverted-attention-mask.ckpt"
output_path: "/path/to/predictions.csv"
device: auto # auto selects CUDA, Apple MPS, or CPU; set mps to require MPS
# Optional: run a reproducible random subset of eligible images.
sampling:
count: 1000 # or use fraction: 0.1; leave both null for all images
seed: 42
Then run:
python forecasting/inference.py --config forecasting/inference_config.yaml
This writes output_path (a CSV of timestamp/prediction/groundtruth). Per-patch
flux contribution maps and per-image attention weights are saved
automatically alongside it whenever flux_path / weight_path are set in the
config — set model_params.no_flux: true or model_params.no_weights: true to
skip either.
3) Evaluate
Edit forecasting/evaluation_config.yaml to point at the predictions
CSV and data directories, then run:
python forecasting/evaluation.py --config forecasting/evaluation_config.yaml
This computes metrics (MSE, MAE, R²) and generates plots under
evaluation.output_dir. When the CSV contains Gaussian uncertainty columns,
evaluation also writes metrics/uncertainty_metrics.csv with NLL, 68%/95%
coverage, sharpness, and standardized-residual diagnostics for the full dataset
and each Quiet/C/M/X class. The corresponding reliability curve and residual
histogram are saved as plots/uncertainty_calibration.png.
Set plotting.inference_patch_dir to inference's patch output folder to save
one figure per matching CSV timestamp under plots/patch_maps/. Each figure
shows available flux and square-root variance contribution maps. Set
plotting.aia_dir and plotting.aia_wavelength to place the matching AIA
channel beside them. All panels use the lower-left image origin;
plotting.max_patch_maps can limit large runs. Flux and uncertainty panels
share one logarithmic scale from the smallest positive to largest value
across all matching patch maps. Zero values are masked on the log scale.
Set plotting.patch_map_class_source to groundtruth or predictions to save
figures under plots/patch_maps/Below-B/, B/, C/, M/, or X/ using the
same flux boundaries as evaluation metrics. Leave it null for a flat folder.
Evaluation shows progress while scanning the maps for the shared color scale
and while saving the figures. Existing PNGs are skipped when evaluation is
rerun, so an interrupted plot run resumes with the remaining figures.
4) Train your own model (optional)
Unlike inference, training expects aia_dir/sxr_dir each to have train/,
val/, and test/ subfolders of paired .npy files — exactly what
data/build_dataset.py and the Hugging Face download path produce.
The maintained local + global Gaussian model uses one global query and a
weighted final-prediction Huber loss. Edit
training/train_coupled_gaussian.yaml for its architecture, mean loss,
uncertainty settings, data paths, and W&B settings. For the released
deterministic model, use training/train_deterministic.yaml.
To encourage predictions above and below the one-to-one line to balance, set
mean_loss.bias_penalty_weight in either training config. The default is 0;
0.1 is a starting point for a sweep. The added loss is the weight times the
mean of the squared signed bias within each GOES class present in the batch,
using normalized log10 flux. Each represented class contributes equally; the
existing Huber loss retains its configured class weights. Compare
val_class/<class>/bias_dex with validation MSE and RMSE before choosing a
weight. A class contributes to the penalty only in batches where it appears.
Optional vit_architecture.global_attention_heads,
global_head_hidden_dim, and global_attention_dropout change only the
coupled model's global head. Omit them to use the architecture defaults saved
in the maintained checkpoint.
python training/train.py --config training/train_coupled_gaussian.yaml
Training logs to Weights & Biases and saves checkpoints to
data.checkpoints_dir.
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.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| helio_foxes-1.0.2.tar.gz | 138.7 kB | With provenance | Details for helio_foxes-1.0.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| helio_foxes-1.0.2-py3-none-any.whl | Python 3 | none | any | Details for helio_foxes-1.0.2-py3-none-any.whl |
Total release size: 256.2 kB
Release files / helio_foxes-1.0.2.tar.gz
| Download URL | helio_foxes-1.0.2.tar.gz |
|---|---|
| Size | 138.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5570d53dcbcc44c27341d9c7a7b33f90593515269bb508f138292fbf28b0fb15
|
|
BLAKE2b-256 checksum How to use checksums |
884697f271060fb67966cfc54c0c80be79930d2ab880198d760fab2f97c05c38
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 19, 2026.
Transparency logRelease files / helio_foxes-1.0.2-py3-none-any.whl
| Download URL | helio_foxes-1.0.2-py3-none-any.whl |
|---|---|
| Size | 117.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b35f9323d5b6ff8ff24077bd0e95b973145a77d494bb44b7f006a63c6c415d69
|
|
BLAKE2b-256 checksum How to use checksums |
aee3ced33a1525de11868b85be09550530d1b1da0103ef8a14753f420585a37a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 19, 2026.
Transparency logSecurity for helio-foxes 1.0.2
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.
Attestation for helio_foxes-1.0.2.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 19, 2026.
Transparency logA 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.