First Look
Two complementary ways to get a first impression of a simulation output:
quicklook— a fixed, one-call dashboard (fast, budgeted): surface-density maps along each axis (plus stellar & dark-matter maps when particles are present), the ρ–T phase diagram, and a global census of cells, particles, masses and SFR.report— the composable form: you choose which cards (projections, phase diagrams, profiles, star-formation history, scalar totals/fractions, cross-datatype ratios) across any datatype, with a cost/runtime estimate beforehand and a wall-time budget.
Use quicklook for the instant overview; reach for report when you want to choose what goes in.
quicklook — the one-call dashboard
quicklook reads the header for instant facts and — unless you ask for header-only — does a single budgeted read to build the dashboard and print a compact summary:
using Mera
q = quicklook(80; path="/sim/cosmo") # the cosmological zoom shown below┌─ Mera quicklook ── output 80 (RAMSES) ───────────────
│ box : 62140.0 kpc levels 6–16 (finest 948.1 pc)
│ grid : ndim 3 · ncpu 16 · nvarh 6
│ time : 11930.0 Myr z = 0.1426
│ particles : 1090895 total — stars 31990 · DM 1058905
│ read : 1749455 cells (full resolution)
│ gas mass : 2.21e15 M⊙
│ nH range : 4.221e-9 … 3.655 cm⁻³
│ T range : 45.13 … 3.933e7 K
│ star mass : 1.22e11 M⊙ DM mass : 1.134e16 M⊙
│ current SFR: 7.254 (10 Myr) · 4.381 (100 Myr) M⊙/yr
└─ 25.93 s ──────────────────────────────────For a cosmological run the reported time is the age of the universe at the snapshot — 11.93 Gyr at $z = 0.1426$ here — not RAMSES' raw conformal info.time, which is negative and not an age. See Cosmological Runs for the conversion and for working in comoving units.

The same call on an isolated disk galaxy (gas + stars, no dark matter) — face-on plus the two edge-on views show the disk and its thickness, and the dark-matter panel is simply omitted:

What you get
The call returns a QuickLookResult:
q.summary— header facts and estimates (box, levels, finest cell, time/redshift, the cell & particle census, masses, density/temperature ranges, read time).q.maps— surface-density projections: gas along each axis (q.maps.z/.x/.y, each anAMRMapsTypewith.maps[:sd]), plus face-onq.maps.stars/q.maps.dmwhen particles are present.q.phase— the ρ–T phase histogram (q.phase.H,q.phase.xedges,q.phase.yedges).q.budget— the global snapshot budget:gas_mass_Msol, and (with particles)stellar_mass_Msol,dm_mass_Msol,n_stars,n_dm, and the current SFR (sfr10,sfr100,sfr_mean, seesfr_snapshot).
Selecting components & projections
By default the dashboard shows every component present, with the three gas projections. Two keywords trim it to exactly what you want (and skip the reads you don't need):
datatypes— any subset of[:hydro, :stars, :dm].[:hydro]shows gas only;[:stars]or[:dm]show that population's face-on Σ and skip the gas read entirely (faster). The census and panels adapt to whatever was read.directions— any subset of[:z, :x, :y]for the gas maps (:z= face-on,:x/:y= edge-on).directions=[:z]gives a single face-on map — the most compact dashboard.
quicklook(300; path="/sim", directions=[:z]) # one gas projection (compact)
quicklook(300; path="/sim", datatypes=[:hydro]) # gas only — no particle maps
quicklook(300; path="/sim", datatypes=[:stars]) # stellar map only (gas read skipped)
quicklook(300; path="/sim", datatypes=[:dm]) # dark-matter map only
quicklook(300; path="/sim", datatypes=[:hydro, :stars], directions=[:z, :x]) # face-on + one edge-onBudgeted reading — fast on big outputs
quicklook reads gas and particles differently, so it stays quick on large simulations:
read=false— header only (sub-second): box, levels, finest cell, ncpu, fields, time/redshift, the particle census — no field data read.budget— a gas cell-count cap (default2_000_000). If the full output is predicted larger, only the coarse AMR levels are read (spatially complete, lower resolution); the result is flaggedsampled=trueand gas-derived numbers are labelled approximate.lmaxoverrides the choice.- Particles are read in full by default (a particle file is tiny next to the AMR hydro), which makes the stellar/DM mass and SFR exact even when the gas read is coarse.
quicklook(300; path="/sim/mw", read=false) # instant header facts only
quicklook(300; path="/sim/mw", budget=500_000) # cap the gas read on a huge outputThe fast estimates are reliable for extensive totals but not for peak quantities:
- Gas mass — exact even on a coarse read: de-refinement is mass/volume-conserving, so the total is unchanged (measured 0.00% error reading ⅓ of the cells).
- Stellar / dark-matter mass, counts, SFR — within ~10% under a particle subsample (an unbiased estimate scaled by 1/fraction; noisier for rarer, clustered sub-populations).
- nH / T ranges — lower bounds on a coarse read: the densest, hottest gas lives in the finest cells, which coarsening averages away (the maxima can read 50–90% low). For the true extremes, read at full resolution.
The dashboard marks the coarse read (⚠), labels gas mass mass-conserving, and flags the ranges as peaks smoothed — so each number says how far to trust it.
Very large particle runs — particle_subsample
For runs where even reading all particle positions is the cost, particle_subsample reads only ~that fraction of the particle CPU files — skipping whole files, so it cuts both I/O and peak memory. RAMSES load-balances its domains to ~equal particles per CPU, so this reads ~that fraction of the particles; the census, masses and SFR are then scaled up by 1/fraction and flagged ⚠ approximate (an unbiased estimate for the total, noisier for rarer/clustered sub-populations):
quicklook(300; path="/sim/cosmo", particle_subsample=0.1) # read ~10% of particle filesThe same subsample keyword is available directly on getparticles (subsample=0.1); scale extensive quantities by 1/subsample for whole-snapshot estimates. For a localized region instead, getparticles(info; xrange=…) reads only the overlapping CPU domains.
Plotting
quicklookplot renders the multi-panel dashboard — gas Σ along x/y/z, face-on stellar & dark-matter Σ (when present), the ρ–T phase diagram, and a text census — with colorblind-safe colormaps (needs a Makie backend):
using CairoMakie
q = quicklook(300; path="/sim/mw")
fig = quicklookplot(q)
CairoMakie.save("quicklook.png", fig)report — composable cards
report turns a simulation output into one composable first-look summary: you pick which quantities and Mera functions to combine — projections, phase diagrams, profiles, star-formation history, scalar totals or fractions, cross-datatype ratios — across any datatype (hydro, particles, gravity, RT, clumps), and render the result as a text dashboard, a plot grid, or a saved file. Before it runs you get a cost/runtime estimate, and an optional budget keeps it within a wall-time target.
report(400; path="/sim") # default: Σ map + ρ–T phase + disk ρ(R) profile + SFR history (ascii)The no-argument default is the quicklook figures (gas Σ map · ρ–T phase · cylindrical density profile) plus a star-formation-history card — matching the star formation quicklook headlines in its census; the SFR card skips gracefully on an output without star particles. To compose your own, list cards:
report(400; path="/sim", output=:ascii, cards=[
ProjectionCard(:hydro, :sd; unit=:Msol_pc2, pxsize=[100., :pc]), # surface-density map
PhaseCard(:hydro, :rho, :T; weight=:mass, xunit=:nH, yunit=:K), # ρ–T phase diagram
ProfileCard(:hydro, :r_cylinder, :rho; weight=:mass, nbins=40, # disk radial density profile
geometry=:cylindrical, center=[:bc], range_unit=:kpc, xunit=:kpc, unit=:nH, yscale=:log),
ScalarCard(:hydro, :mass; reduce=:sum, unit=:Msol), # absolute gas mass
ScalarCard(:hydro, :mass; fraction=true, label="cold_frac", # cold-gas mass fraction
mask = o -> getvar(o, :T, :K) .< 1e4),
SFRCard(:particles; tbinsize=50.0), # star-formation history
])report reads each datatype once (with only the variables the cards actually need, via getvar_requirements), computes every card, and returns a QuickReport — which you can re-render or analyse further. With a Makie backend loaded, render(rep, :plot) lays the cards out as a figure grid:
using CairoMakie
rep = report(300; path="/sim", output=:none, cards=[ … ])
fig = render(rep, :plot; ncols=2)
CairoMakie.save("report.png", fig)
The cards
Each card names a datatype (first argument), a quantity, optional unit, and card-specific options. Any name getvar understands works — including your own add_field fields.
Resolution on a ProjectionCard is set either by pxsize=[value, unit] (physical size of a pixel) or by res (pixels per side); pxsize wins when both are given. Budget mode scales whichever you used, so report(...; budget_s=...) works the same either way.
| Card | Wraps | Example |
|---|---|---|
ProjectionCard | projection | ProjectionCard(:hydro, :sd; unit=:Msol_pc2, pxsize=[100., :pc], direction=:edgeon) |
PhaseCard | phase | PhaseCard(:hydro, :rho, :T; weight=:mass, xunit=:nH, yunit=:K) |
ProfileCard | profile | ProfileCard(:hydro, :r_sphere, :vz; weight=:mass, nbins=40) |
ScalarCard | a reduction | ScalarCard(:particles, :mass; reduce=:sum, unit=:Msol) |
SFRCard | sfr | SFRCard(:particles; tbinsize=50.0, mode=:probability) |
CombinedCard | cross-datatype | baryon_fraction() |
Absolute values vs fractions
Every aggregating card supports a fraction toggle. ScalarCard(...; fraction=true) divides by the total of relative_to (or the same variable); mask restricts the rows:
ScalarCard(:hydro, :mass; reduce=:sum, unit=:Msol) # absolute [M⊙]
ScalarCard(:hydro, :mass; fraction=true, mask = o -> getvar(o,:T,:K).<1e4) # fraction of totalProfiles: geometry & axis scale
A ProfileCard's geometry sets the radial coordinate. For a disk galaxy use xvar=:r_cylinder, geometry=:cylindrical — radius in the disk plane — which is the default in the quicklook trio; a halo/spheroid is better with :r_sphere, geometry=:spherical. yscale controls the plotted y-axis: :log (log₁₀), :identity (linear), or :auto (log when the profile is positive and spans ≳ 1.5 decades, e.g. density). So the default density profile is cylindrical with a log y-axis.
ProfileCard(:hydro, :r_cylinder, :rho; geometry=:cylindrical, weight=:mass, unit=:nH, yscale=:log) # disk
ProfileCard(:hydro, :r_sphere, :rho; geometry=:spherical, weight=:mass, unit=:nH) # halo
ProfileCard(:hydro, :r_cylinder, :vz; geometry=:cylindrical, weight=:mass, yscale=:identity) # signed → linearStar formation
SFRCard (and the standalone sfr) build the star-formation history from the star particles (birth ≠ 0): mode=:none gives M⊙/yr, mode=:probability the normalised SFH. For a single-number current SFR from one snapshot use sfr_snapshot — the stellar mass formed within a recent window divided by that window (e.g. 5/10/100 Myr), plus the lifetime mean. Both prefer a stored initial-mass field when present (mass=:auto), since the current particle mass underestimates the formed mass after stellar mass loss. Outputs without stars yield zeros, not an error.
Cross-datatype cards
CombinedCard reads several datatypes and combines them. Two are built in:
baryon_fraction() # (gas + stars) / (gas + stars + dark matter) [hydro + particles]
clump_mass_fraction() # total clump mass / total gas mass [clumps + hydro]
# your own:
CombinedCard([:hydro, :particles]; label="gas_to_star") do d
sum(getvar(d[:hydro], :mass, :Msol)) / sum(getvar(d[:particles], :mass, :Msol))
endOff-axis maps & custom fields
Projection cards take the same view controls as projection — direction=:faceon/:edgeon tilt the map to the disk (the report automatically reads the velocities needed to orient it):
ProjectionCard(:hydro, :sd; unit=:Msol_pc2, pxsize=[100., :pc], direction=:edgeon) # edge-on Σ mapSee Off-axis Projection for the full set of view options. Any field you register with add_field (see Derived Fields & add_field) is usable as a card quantity, and the report reads only its dependencies:
add_field(:vmag, (o,d) -> sqrt.(d[:vx].^2 .+ d[:vy].^2 .+ d[:vz].^2);
depends_on=[:vx,:vy,:vz], unit=:km_s)
ProfileCard(:hydro, :r_cylinder, :vmag; weight=:mass, nbins=40) # uses the custom fieldDatatypes & graceful skipping
Scalar and profile cards work on hydro, particles, gravity, and clumps; projection cards work on hydro and particles (gravity/RT projection needs hydro pairing). A card is skipped with a note — never an error — when its datatype is absent from the output, or when it needs a variable that isn't stored (e.g. an RT :xHII card on a non-RT run). So a "kitchen-sink" plan runs unchanged on a hydro-only output.
On an RT simulation the standard quantities are shown correctly: RAMSES stores the radiative- transfer fields (photon densities, fluxes, ionization fractions) in separate files read by getrt, so they are not part of nvarh — quicklook and the hydro cards read the usual gas variables (:rho, :vx…, :p) and derive :sd, :T, the ρ–T phase and the budget exactly as on a non-RT run. The RT fields themselves are not in the quicklook dashboard, but a report can include them directly with an RT projection card — the engine reads the RT data via getrt, and an RtDataType projects its photon fields (mass-weighting auto-falls back to volume, since RT carries no mass):
report(output; path="/sim", cards=[ProjectionCard(:rt, :Np1; pxsize=[100., :pc])]) # photon density, group 1
Cost estimate & budget
Inspect a plan's predicted cost with zero I/O before running:
plan = ReportPlan(400; path="/sim", cards=[...])
preview(plan) # prints a per-card cells/time table + total
estimate(plan) # the same numbers as a NamedTupleThe model self-calibrates — every real report learns this machine's timing; calibrate!(400; path="/sim") runs a quick active calibration. Keep a run within a wall-time target with the budget, which drops the read level first, then shrinks resolution/bins:
report(plan; budget_s=10.0) # auto-fit ~10 s
downsample(plan, 10.0) # or get the trimmed plan explicitlyOutput backends
rep = report(plan; output=:none) # compute only, render later
render(rep, :ascii) # text dashboard (default)
render(rep, :plot; ncols=2) # Makie Figure grid (needs `using CairoMakie`)
render(rep, :jld2; filename="r.jld2") # full round-trip
render(rep, :file; mode=:dir, prefix="r") # report.jld2 + summary.txt + one PNG per card
loadreport("r.jld2") # reload a saved QuickReportPlotting lives in a package extension — load any Makie backend (using CairoMakie) and :plot / :file mode=:dir activate. Without one, those backends print a clear "load CairoMakie" message; everything else (ascii / jld2 / :file mode=:bundle) works with no extra dependencies.
Working with the result
rep.cards # Vector{ReportResultCard}: each has .label .kind .datatype .data .meta
rep.cards[1].data.z # e.g. the raw projection matrix — re-analyzable / re-plottable
rep.cost.per_card # (label, seconds) per card
rep.summary # header facts (box, levels, time/redshift, sampled?)
rep.provenance # mera/julia version, timestamp, the planAPI
The result types (ReportPlan, QuickReport, ReportResultCard, QuickLookResult) and the card recipe types are documented in the Complete API Reference.
Mera.report — Function
report(plan::ReportPlan; output=:ascii, budget_s=nothing, verbose=true)
report(sim_output::Int; path=".", cards=:default, output=:ascii, lmax=-1, budget=2_000_000, budget_s=nothing, verbose=true)Run a composable first-look [ReportPlan] and return a [QuickReport]. Each datatype is read once with the minimal variable set unioned across its cards (via getvar_requirements). output (the backend) is rendered immediately — :ascii prints a dashboard, :jld2/:file write the report — and the QuickReport is returned for re-rendering / re-analysis.
report(1; path=sim, output=:ascii, cards=[
ProjectionCard(:hydro, :sd; unit=:Msol_pc2, res=512),
PhaseCard(:hydro, :rho, :T; weight=:mass, xunit=:nH, yunit=:K),
ScalarCard(:hydro, :mass; reduce=:sum, unit=:Msol),
])Mera.preview — Function
Mera.estimate — Function
estimate(plan::ReportPlan) -> NamedTupleZero-I/O runtime estimate for a [ReportPlan]: returns (per_card, read_s, compute_s, total_s, level, cells, sampled, calibrated) where per_card is a vector of (label, kind, datatype, cells, seconds). Absolute times are advisory until the cost model is calibrate!d (calibrated=false ⇒ treat as ±2×).
Mera.downsample — Function
downsample(plan::ReportPlan, target_s) -> ReportPlanReturn a new plan trimmed to an estimated wall-time of target_s seconds: first drop the read level (fewest cells — helps every card), then shrink projection resolution and histogram bins. Used by report(...; budget_s=target_s). Never goes below levelmin / minimum sane resolution.
Mera.calibrate! — Function
calibrate!(output; path=".", budget=200_000) -> CostModelActively calibrate the cost model for this machine/output by running a tiny report (one coarse level + small projection/phase/profile/scalar) and learning the timing coefficients. ~0.5–3 s, once. (The model also self-calibrates passively after every real report.)
Mera.render — Function
render(report::QuickReport, backend::Symbol; kwargs...)Render a [QuickReport] to a backend: :ascii (text dashboard, default), :jld2 (full round-trip via loadreport), :file (a .jld2 + _summary.txt bundle), or :plot (requires a Makie package extension — using CairoMakie).
Mera.loadreport — Function
loadreport(filename) -> QuickReportReload a [QuickReport] written with render(report, :jld2) (or :file).
Mera.sfr — Function
sfr(p::PartDataType; tbinsize=10.0, trange=[0.0, missing], mass=:auto, mask=[false],
mode=:none, closed=:left) -> (t_Myr, sfr)Star-formation history from the star particles: t_Myr are the left bin edges [Myr] and sfr is the star-formation rate per bin M⊙/yr.
Star particles are selected by the universal RAMSES sentinel birth ≠ 0 (non-star particles have birth == 0); the sign/scale of the stored birth time varies between runs, so a birth > 0 test is not reliable. The formation-time axis is physical and RAMSES-version aware:
non-cosmological runs — the proper birth time
getvar(:birth, :Myr)(formation time in the run's own time coordinate; it may be negative — the origin is arbitrary and does not affect the SFH shape).cosmological runs —
:birthis a super-conformal time (≤ 0 at a = 1), not a physical time, sosfrbins the physicalgetvar(:formation_time, :Myr)(cosmic time of formation, from the Friedmann table) instead.tbinsize— bin width in Myr.trange—[t0, t1]in Myr; each entry defaults tomissing⇒ the earliest / latest stellar formation time, so the bins span exactly the star-formation history.mass— mass field to integrate;:auto(default) prefers a stored initial-mass column (:minit,:mass_init, …) and falls back to current:mass. SFR should use the initial stellar mass; current mass underestimates it by post-formation mass loss.mask— a Bool vector over the particles (length == number of particles) to subselect.mode—:none(M⊙/yr) or:probability(normalised SFH fraction).eta_sn,t_sn_delay— SN mass-loss correction for runs that store only the current mass: a star older thant_sn_delayMyr (SN onset, default 5) has shed a fractioneta_snof its birth mass, so its mass is rescaled by1/(1-eta_sn)to recover the initial mass. Defaulteta_sn=0is a no-op; ignored (with a warning) when an initial-mass field is used — it is already the birth mass.
t, s = sfr(parts; tbinsize=50.0) # SFR [M⊙/yr] vs t [Myr]
t, s = sfr(parts; mass=:minit) # force a specific initial-mass field
t, s = sfr(parts; eta_sn=0.2) # reconstruct birth mass from current mass (20% SN loss)See also sfr_snapshot for the current SFR from a single snapshot.
Mera.ProjectionCard — Type
ProjectionCard(kind, var; unit=:standard, weight=:mass, res=256, pxsize=nothing, direction=:z, center=[:bc], range_unit=:standard, label="")A projection card (surface-density / mass-weighted map) for a ReportPlan.
Resolution is set either by res (pixels per side) or by pxsize=[value, unit] (physical size of a pixel, e.g. [100., :pc]). pxsize wins when both are given. Because a card is built before the simulation is read, a pxsize cannot be converted to a pixel count until report runs — estimate/preview therefore resolve it against the box at that point.
Mera.PhaseCard — Type
PhaseCard(kind, xvar, yvar; weight=:mass, nbins=(80,80), xscale=:log, yscale=:log, xunit=:standard, yunit=:standard, label="")A phase (2-D histogram) card for a ReportPlan.
Mera.ProfileCard — Type
ProfileCard(kind, xvar, yvar=nothing; weight=:mass, nbins=40, geometry=:none, unit=:standard, xunit=:standard, range_unit=:standard, center=[:bc], yscale=:auto, label="")A profile (1-D radial/other profile) card for a ReportPlan. For a disk galaxy use xvar=:r_cylinder, geometry=:cylindrical (radius in the disk plane); :r_sphere, geometry=:spherical suits a halo/spheroid. yscale sets the y-axis when plotted: :log/:log10 (log₁₀), :identity (linear), or :auto (log when the profile is positive and spans ≳ 1.5 decades, e.g. density).
Mera.ScalarCard — Type
ScalarCard(kind, var; reduce=:sum, unit=:standard, fraction=false, relative_to=nothing, mask=nothing, label="")A scalar reduction card (reduce ∈ :sum,:mean,:extrema,:count). fraction=true divides by the total of relative_to (or var); mask=obj->BitVector restricts the rows.
Mera.SFRCard — Type
SFRCard(kind=:particles; tbinsize=10.0, trange=[0.0,missing], unit=:Msol_yr, mode=:none, mass=:auto, mask=nothing, label="")A star-formation-history card (sfr). mode=:probability gives the normalised SFH (a fraction); mass=:auto prefers a stored initial-mass field; mask=obj->BitVector subselects.
Mera.CombinedCard — Type
CombinedCard(datatypes, compute; unit=:fraction, label="combined")
CombinedCard(datatypes; unit=:fraction, label="combined") do datas … endA cross-datatype scalar card. compute(datas) receives a Dict{Symbol,Any} of the read data objects for datatypes and returns a number. Computed only if all datatypes are present. See the built-ins baryon_fraction and clump_mass_fraction.
Mera.baryon_fraction — Function
baryon_fraction(; label="baryon_fraction")Cross-datatype card: (gas + stars) / (gas + stars + dark matter), reading hydro + particles.
Mera.clump_mass_fraction — Function
clump_mass_fraction(; label="clump_mass_fraction")Cross-datatype card: total clump mass / total gas mass, reading clumps + hydro.
See also
- Derived Fields & add_field — register custom quantities usable as cards.
- Off-axis Projection —
:faceon/:edgeonand arbitrary lines of sight. - Profiles & Phase Diagrams — the profile/phase tools behind the cards.
- Star-Formation Rate — the standalone
sfr/sfr_snapshotand the cosmological handling.