Views
No views yet

1FOXES
2├── download
3│ ├── hugging_face_data_download.py # Recommended: HF Hub -> .npy (streamed, or from local parquet)
4│ ├── hf_download_config.yaml # Config for hugging_face_data_download.py
5│ ├── download_sdo.py # Advanced: raw AIA download from JSOC (needs data/build_dataset.py after)
6│ ├── sdo_download_config.yaml # Config for download_sdo.py
7│ ├── download_sxr.py # Advanced: raw GOES SXR download via SunPy Fido (needs data/build_dataset.py after)
8│ └── sxr_download_config.yaml # Config for download_sxr.py
9├── data
10│ ├── build_dataset.py # Runs the full raw -> processed pipeline below in one command
11│ ├── build_dataset_config.yaml # Config for build_dataset.py
12│ ├── clean_aia.py # Drop AIA FITS files with a bad DATE-OBS timestamp
13│ ├── convert_aia.py # Raw AIA FITS -> paired 512x512 .npy stacks (itipy)
14│ ├── combine_sxr.py # Combine raw multi-satellite GOES files into per-satellite CSVs
15│ ├── align_aia_sxr.py # Match AIA timestamps to GOES CSVs -> per-timestamp SXR .npy
16│ ├── split_train_val_test.py # Split processed AIA/SXR into train/val/test (use for training a new model only)
17│ └── sxr_normalization.py # Compute log-space mean/std over SXR .npy files for training
18├── forecasting
19│ ├── dataset.py # AIAGOESDataset / AIAGOESDataModule: loads paired AIA + SXR .npy files
20│ ├── model.py # ViTLocal: Vision Transformer with patch flux heads
21│ ├── inference.py # Run a checkpoint over a folder of data; writes predictions.csv
22│ ├── inference_config.yaml # Config for inference.py
23│ ├── evaluation.py # Compute metrics and generate evaluation plots
24│ ├── evaluation_config.yaml # Config for evaluation.py
25│ └── trained_weights_and_normalization/ # 3 released checkpoints + normalized_sxr.npy (see below)
26├── training
27│ ├── train.py # Train ViTLocal with PyTorch Lightning + Weights & Biases logging
28│ ├── train_config.yaml # Config for train.py
29│ └── callbacks.py # W&B callbacks: SXR pred-vs-true plots, attention map visualization
30└── requirements.txt # Python dependencies1git clone https://github.com/griffin-goodwin/FOXES.git
2cd FOXES1conda create -n foxes python=3.14 -y
2conda activate foxes
3pip install -r requirements.txt1conda env create -f foxes.yml
2conda activate foxes.npy layout inference expects — no separate processing step:python download/hugging_face_data_download.py --config download/hf_download_config.yamldownload/hf_download_config.yaml first to set aia_dir/sxr_dir, which
splits to pull, and whether to subsample.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.1# 1) Raw AIA FITS from JSOC (requires a registered email)
2python download/download_sdo.py --config download/sdo_download_config.yaml
3
4# 2) Raw GOES XRS data via SunPy Fido
5python download/download_sxr.py --config download/sxr_download_config.yaml
6
7# 3) Clean + convert AIA, combine + align SXR -> paired .npy (see data/build_dataset_config.yaml)
8python data/build_dataset.py --config data/build_dataset_config.yamldata/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 — splits aia.processed_dir/output.sxr_dir into
train//val//test/ subfolders (date ranges or a month-based default;
see the split: block in the config).sxr_normalization.compute: true — computes SXR normalization stats from
the train split (requires steps.split to have run first).inference.py at a folder of paired .npy files, one file per timestamp:1/your/aia_dir/
2├── 2023-08-01T00:00:00.npy # (7, 512, 512) float32 — one channel per AIA wavelength
3├── 2023-08-01T00:01:00.npy
4└── ...
5
6/your/sxr_dir/ # only needed if you have ground truth to compare against
7├── 2023-08-01T00:00:00.npy # scalar xrsb_flux value
8└── ...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.prediction_only: "true" in the config and data.sxr_dir is ignored entirely.forecasting/trained_weights_and_normalization/, differing only in the
self-attention mask they were trained with (see mask_mode in
training/train_config.yaml) — each checkpoint carries its own mask, so
nothing else needs to change to switch between them, just 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. |
forecasting/inference_config.yaml:1data:
2 aia_dir: "/path/to/your/aia_data"
3 sxr_dir: "/path/to/your/sxr_data" # omit/ignore if prediction_only
4 sxr_norm_path: "forecasting/trained_weights_and_normalization/normalized_sxr.npy"
5 checkpoint_path: "forecasting/trained_weights_and_normalization/inverted-attention-mask.ckpt"
6
7output_path: "/path/to/predictions.csv"python forecasting/inference.py --config forecasting/inference_config.yamloutput_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.forecasting/evaluation_config.yaml to point at the predictions
CSV and data directories, then run:python forecasting/evaluation.py --config forecasting/evaluation_config.yamlevaluation.output_dir.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.training/train_config.yaml:1base_data_dir: "/path/to/processed_data" # holds AIA_processed/ and SXR_processed/
2base_checkpoint_dir: "/path/to/checkpoints"
3
4gpu_ids: -1 # -1 = CPU, 0 = GPU 0, [0,1] = specific GPUs, "all" = every GPU
5batch_size: 6
6epochs: 150
7
8vit_architecture:
9 mask_mode: inverted # inverted (released model) | local | none (full/global attention)
10 local_window: 9
11
12wandb:
13 entity: "" # your W&B username or team namepython training/train.py --config training/train_config.yamltraining/callbacks.py) and
saves the top 10 checkpoints by validation loss to data.checkpoints_dir,
ready to point forecasting/inference_config.yaml at.1@software{FOXES,
2 title = {{FOXES: A Framework For Operational X-ray Emission Synthesis}},
3 institution = {Frontier Development Lab (FDL)},
4 repository-code = {https://github.com/griffin-goodwin/FOXES},
5 version = {v1.0},
6 year = {2026}
7}