End-to-end workflow#
This guide follows one ForestFlow prediction from simulation data to P3D and P1D. Loading the archive is useful for inspection and validation but is not required merely to evaluate the pretrained emulator.
Data flow#
![digraph forestflow_workflow {
graph [rankdir=LR, bgcolor="transparent"];
node [shape=box, style="rounded,filled", fillcolor="#eef4fb"];
Archive [label="GadgetArchive3D\nsimulation P3D/P1D"];
Inputs [label="cosmology + IGM\ninput mapping"];
Emulator [label="P3DEmulator\ncINN"];
Coefficients [label="Arinyo coefficient\nmapping"];
Model [label="ArinyoModel +\nlinear theory"];
Spectra [label="P3D_Mpc / P1D_Mpc"];
Validation [label="leave-one-out\nresidual covariance"];
Archive -> Inputs [label="training/validation"];
Inputs -> Emulator;
Emulator -> Coefficients;
Coefficients -> Model;
Model -> Spectra;
Archive -> Validation;
Spectra -> Validation;
}](_images/graphviz-179e4538980f0a2295a9b3054b18ef31eff79ec2.png)
1. Inspect the archive#
GadgetArchive3D extends the LaCE archive with measured P3D, P1D,
and precomputed Arinyo fits:
from forestflow.archive import GadgetArchive3D
archive = GadgetArchive3D()
training = archive.training_data
testing = archive.get_testing_data("mpg_central")
sample = testing[0]
print(sample["z"], sample["cosmo_params"])
Archive files retain historical keys such as k_Mpc and
p1d_Mpc. Public prediction code uses k_iMpc,
P1D_Mpc, and P3D_Mpc; see Scientific conventions and contracts.
2. Load the emulator#
from forestflow.P3D_cINN import P3DEmulator
emulator = P3DEmulator(key="forest_mpg")
print(emulator.input_labels)
print(emulator.output_labels)
input_labels is the authoritative normalized input order. Prefer a
mapping over a positional array.
3. Predict Arinyo coefficients#
The compressed cosmology must describe the same cosmology supplied to the Arinyo model:
from lace.cosmo import cosmology
z = 3.0
cosmo = cosmology.Cosmology()
linear_parameters = cosmo.get_linP_Mpc_params(z=z, kp_Mpc=0.7)
emulator_input = {
"Delta2_p": linear_parameters["Delta2_p"],
"n_p": linear_parameters["n_p"],
"mF": 0.23,
"sigT_Mpc": 0.10,
"gamma": 1.21,
"kF_Mpc": 14.2,
}
arinyo = emulator.evaluate(emulator_input, seed=0)
The result is keyed by emulator.output_labels. Inputs outside the
training domain are extrapolations; inspect the archive training sample before
interpreting them.
4. Compute P3D and P1D#
import numpy as np
from forestflow.model_p3d_arinyo import ArinyoModel
model = ArinyoModel(cosmo)
linear = model.linear_theory(z)
k_iMpc = np.geomspace(0.1, 4.0, 80)
mu = np.linspace(0.0, 1.0, 6)
k2d_iMpc, mu2d = np.meshgrid(k_iMpc, mu, indexing="ij")
P3D_Mpc = model.P3D_Mpc_k_mu(
linear, z, k2d_iMpc, mu2d, arinyo
)
P1D_Mpc = model.P1D_Mpc(linear, z, k_iMpc, arinyo)
The outputs match their input grid shapes. For velocity coordinates use
forestflow.p1d.P1D_kms() with k_ikms and
dkms_diMpc = H(z)/(1+z).
5. Interpret uncertainty#
P3DEmulator.evaluate averages cINN latent realizations. Increasing
Nrealizations reduces Monte Carlo noise in that mean; their scatter is
not automatically a calibrated prediction error, and evaluate does not
return a covariance.
For emulator uncertainty, use leave-one-simulation-out residuals from
forestflow.covariance. Their covariance describes prediction residuals
over the validated simulations. Gaussian-noise helpers and the covariance
tutorials instead estimate finite-volume/sample variance. These uncertainties
answer different questions and should not be interchanged without an explicit
analysis model.
Continue with Notebook guide, consult Scientific conventions and contracts for array and unit contracts, and use API reference for individual functions.
Training a new emulator#
With train=True and use_val_set=True, every improvement in
validation negative log likelihood snapshots the model state. After training,
ForestFlow restores and saves the minimum-validation-loss state instead of the
final epoch. Metadata records the zero-based best_epoch and
best_validation_loss, and loading exposes both as emulator attributes.
Without validation, the final epoch is saved and
best_validation_loss is None.