Derived Fields & add_field
Mera computes a large catalogue of derived quantities on demand through getvar — temperature, sound speed, Mach number, cylindrical/spherical velocities, specific angular momentum, Jeans length, kinetic/thermal energy, and many more. You ask for them by name and Mera builds them from the raw stored variables:
gas = gethydro(getinfo(output, path))
getvar(gas, :T, :K) # temperature
getvar(gas, :mach) # Mach number
getvar(gas, :ekin, :erg) # kinetic energy
getvar(gas, [:vr_cylinder, :vϕ_cylinder], :km_s; center=[:bc])These derived names also work everywhere getvar is used internally — in projection, profile, phase, and friends.
For the full set of formulas behind every derived quantity (thermodynamics, velocities, angular momentum, Mach numbers, Jeans/collapse, gravity) and the aggregate statistics (msum, center_of_mass, bulk_velocity, wstat), see How Quantities Are Computed.
Conventions for selected quantities
A few derived quantities carry physical assumptions worth stating explicitly:
- Jeans length
:jeanslengthuses the standard form $λ_J = c_s\,\sqrt{\dfrac{3π}{32\,G\,ρ}}$ (and:jeansmass/:jeansnumberfollow from it). This is one of several Jeans-length conventions in the literature; factors of order unity differ between them. - Magnetosonic Mach numbers
:mach_alfven,:mach_fast,:mach_slowrequire the magnetic-field components:bx,:by,:bz(an MHD run) and error otherwise. The B field is taken in RAMSES code units and converted to Gaussian-CGS internally (Alfvén speed $v_A = B/\sqrt{4πρ}$); fast/slow use $v_{f}=\sqrt{c_s^2+v_A^2}$ and the isotropic $v_{s}=c_s v_A/\sqrt{c_s^2+v_A^2}$. All three are dimensionless. (Because they need the field components,getvar_requirementslists:bx,:by,:bz,:rhoamong their dependencies.) - Escape speed
:escape_speed$= \sqrt{-2φ}$ is defined only where the potential $φ<0$ (bound); unbound cells ($φ≥0$, possible near boundaries) are clamped to0rather than erroring. - Cosmological-only quantities —
:overdensity/:delta(hydro) and:age-relatives:formation_time/:formation_redshift/:zform(particles) — are defined only for cosmological runs and error on non-cosmological output.
The dependency registry
Each derived quantity knows which raw variables it is built from. That graph is queryable:
getvar_requirements(:hydro, :ekin) # [:rho, :vx, :vy, :vz]
getvar_requirements(:hydro, :jeanslength) # [:rho, :p]
getvar_requirements(:hydro, [:sd, :T]) # [:rho, :p]This is what lets the one-call verbs read only what they need instead of the whole hydro state. project(info, :sd) reads just :rho; project(info, :sd; direction=:edgeon) also pulls the velocities required to orient the disk; quicklook reads only :rho and :p. When a requirement cannot be resolved (e.g. a custom field whose dependency is not stored in that output) the readers safely fall back to reading everything.
Adding your own field: add_field
Register a custom derived field once and it behaves like any built-in quantity — including inside projection and profile. This is the equivalent of yt's add_field.
using Mera
# velocity magnitude squared, built from the velocity components
add_field(:vmag2, (obj, deps) -> deps[:vx].^2 .+ deps[:vy].^2 .+ deps[:vz].^2;
depends_on = [:vx, :vy, :vz])
getvar(gas, :vmag2) # works in getvar …
projection(gas, :vmag2) # … and in projection …
profile(gas, :r_cylinder, :vmag2) # … and in profile / phaseThe compute kernel
compute(dataobject, deps):
dataobject— the data object the field is being evaluated on.deps— aDict{Symbol,Vector}holding the arrays named independs_on, already evaluated with the same centering and masking as the outergetvarcall.- Return the field in code units; Mera applies the requested
unit(or this field's defaultunit) for you.
Dependencies may be raw variables, other built-in derived quantities, or even other user fields — they are resolved recursively:
# a field built on top of a built-in derived quantity (:cs, the sound speed)
add_field(:mach_custom, (o, d) -> sqrt.(d[:vx].^2 .+ d[:vy].^2 .+ d[:vz].^2) ./ d[:cs];
depends_on = [:vx, :vy, :vz, :cs])A registered field is a first-class citizen: it flows through getvar, projection, profile and the rest, with its dependencies read and resolved automatically. For example, once :mach_custom is registered, projection(gas, :mach_custom) just works:

Units
Give a field a default unit (it must be a field of info.scale, or :standard for code units). A unit passed at call time overrides the default:
add_field(:rho_msun_pc3, (o, d) -> d[:rho]; depends_on = [:rho], unit = :Msol_pc3)
getvar(gas, :rho_msun_pc3) # returns code-unit ρ scaled by info.scale.Msol_pc3
getvar(gas, :rho_msun_pc3, :standard) # call-time unit override → code unitsOther data types
By default fields are registered for hydro. Register for other kinds (or several at once) with datatypes:
add_field(:speed, (o, d) -> sqrt.(d[:vx].^2 .+ d[:vy].^2 .+ d[:vz].^2);
depends_on = [:vx, :vy, :vz], datatypes = [:hydro, :particle])Valid kinds: :hydro, :gravity, :rt, :particle, :clump.
Managing registered fields
list_fields(:hydro) # names you added for hydro (custom only)
list_fields(:hydro; builtin=true) # built-in derived fields ∪ your custom ones, sorted
field_info(:vmag2) # (; compute, depends_on, unit, description)
delete_field(:vmag2) # remove it (delete_field(name; datatypes=:all) by default)list_fields(kind; builtin=true) is the quickest way to discover what you can ask getvar for on a given data type — it returns the dependency-registry built-ins together with any fields you registered. It covers most but not every built-in quantity (a few specialised fields are computed directly in getvar); for the complete human-readable catalogue call getvar() with no arguments.
The default (builtin=false) lists only the fields you registered, so it starts empty and grows as you add_field (and shrinks again on delete_field):
list_fields(:hydro) # builtin=false (default): custom fields only — none yetSymbol[]add_field(:speed2, (o, d) -> d[:vx].^2 .+ d[:vy].^2 .+ d[:vz].^2; depends_on=[:vx, :vy, :vz])
list_fields(:hydro) # the field you just added now appears1-element Vector{Symbol}:
:speed2delete_field(:speed2)
list_fields(:hydro) # removed again → back to emptySymbol[]With builtin=true the same call instead returns the full catalogue. The lists below are generated live from the registry at doc-build time, so they always match the installed version. Hydro:
list_fields(:hydro; builtin=true)73-element Vector{Symbol}:
:T
:T_rt
:Temp
:Temperature
:beta
:bmag
:bx
:by
:bz
:cellsize
⋮
:vz2
:vθ_sphere
:vϕ_cylinder
:vϕ_cylinder2
:vϕ_sphere
:x
:y
:z
:ϕGravity, RT, particle, clump (same call, different kind):
list_fields(:gravity; builtin=true)17-element Vector{Symbol}:
:a_magnitude
:ar_cylinder
:ar_sphere
:aθ_sphere
:aϕ_cylinder
:aϕ_sphere
:cellsize
:escape_speed
:gravitational_redshift
:r_cylinder
:r_sphere
:specific_gravitational_energy
:volume
:x
:y
:z
:ϕlist_fields(:particle; builtin=true)31-element Vector{Symbol}:
:age
:ekin
:formation_redshift
:formation_time
:h
:hx
:hy
:hz
:l
:lr_cylinder
⋮
:vr_sphere
:vx2
:vy2
:vz2
:vθ_sphere
:vϕ_cylinder
:vϕ_sphere
:zform
:ϕ(rt = list_fields(:rt; builtin=true), clump = list_fields(:clump; builtin=true))(rt = [:cellsize, :r_cylinder, :r_sphere, :volume, :x, :y, :z, :ϕ], clump = [:ekin, :mass, :v, :x, :y, :z])Registered fields live for the current Julia session (they are not persisted to disk). Put your add_field calls in a startup script or at the top of your analysis to make them available every run.
Registered fields also work as quantities in First-Look Reports cards — the report reads only the dependencies your field declares.
Custom units
A field's unit can be an existing info.scale field, :standard, a plain number (a literal code→display factor), or a custom unit you register with add_unit. Registered units work everywhere a unit is accepted — including getvar(obj, var, unit) for built-in quantities:
add_unit(:Msun_per_century, 1e-2) # 1 code-unit value × 1e-2
add_field(:mdot, (o,d) -> d[:rho]; depends_on=[:rho], unit=:Msun_per_century)
getvar(gas, :mass, :Msun_per_century) # also applies to built-in fields
list_units(); delete_unit(:Msun_per_century)Inspecting dependencies
field_dependencies(:hydro, :ekin) # (; direct=[:mass,:v], raw=[:rho,:vx,:vy,:vz])
field_tree(:hydro, :mach) # prints the dependency tree down to raw leavesmach
├─ v
│ ├─ vx (raw)
│ ├─ vy (raw)
│ └─ vz (raw)
└─ cs
├─ p (raw)
└─ rho (raw)See also
Registered fields are used throughout Mera: getvar computes them, projection and profile read only the dependencies they need (via getvar_requirements), and the First Look (quicklook / report) verbs benefit from the same needs-based reading. See also Star-Formation Rate and Clump Finding for fields used in analysis.
API
Mera.add_field — Function
add_field(name::Symbol, compute::Function; depends_on=Symbol[], datatypes=:hydro,
unit::Symbol=:standard, description::String="")Register a user-defined derived field that then behaves like any built-in getvar quantity — it works in getvar, and therefore in projection, profile, phase, etc.
compute(dataobject, deps)— your kernel.depsis aDict{Symbol,Vector}holding the arrays ofdepends_on(already centered / masked consistently). Return the field in code units; the requestedunit(or this field's defaultunit) is applied for you.depends_on— the variables your kernel needs (built-in or other user fields). These are also recorded in the dependency graph sogetvar_requirements(and the read-only-what-you-need logic inproject/quicklook) cover your field.datatypes— a kind symbol or collection of them::hydro,:gravity,:rt,:particle,:clump.unit— default unit symbol (must be a field ofinfo.scale, or:standard).
add_field(:vmag2, (o, d) -> d[:vx].^2 .+ d[:vy].^2 .+ d[:vz].^2; depends_on=[:vx,:vy,:vz])
getvar(gas, :vmag2)
projection(gas, :vmag2)See also delete_field, list_fields.
Mera.delete_field — Function
delete_field(name::Symbol; datatypes=:all)Remove a previously add_field-registered field. datatypes=:all (default) removes it from every kind; otherwise pass a kind symbol or collection.
Mera.list_fields — Function
list_fields(kind::Symbol=:hydro; builtin::Bool=false) -> Vector{Symbol}The registered derived-field names for a data-type kind (:hydro, :gravity, :rt, :particle, :clump), sorted.
By default only the user-added fields (registered with add_field) are returned — this is the back-compatible behaviour. With builtin=true the result also includes the built-in derived quantities known to the dependency registry (FIELD_DEPS[kind]), so you get a single combined list of everything resolvable for that kind:
list_fields(:hydro) # only the fields you added
list_fields(:hydro; builtin=true) # built-in registry fields ∪ your custom fieldsNote: builtin=true reflects the dependency registry, which covers most but not every built-in quantity (a few specialised fields, e.g. some RT-ionization variables, are computed directly in getvar without a registry entry). For the full human-readable catalogue call getvar() with no arguments.
Mera.field_info — Function
field_info(name::Symbol; kind::Symbol=:hydro)The registration record (; compute, depends_on, unit, description) for a user field, or nothing if it isn't registered for that kind.
Mera.field_dependencies — Function
field_dependencies(kind::Symbol, var::Symbol) -> (; direct, raw)Inspect a derived field's dependencies for data-type kind: direct are its immediate dependencies (raw or derived, as declared), raw is the transitive set of physical stored variables it ultimately needs (same as getvar_requirements). Works for built-in and add_field-registered quantities.
Mera.field_tree — Function
field_tree(kind::Symbol, var::Symbol; io=stdout)Pretty-print the dependency tree of a derived field down to its raw leaves (cycle-safe).
Mera.add_unit — Function
add_unit(name::Symbol, factor::Real)Register a custom unit: a value in code units is multiplied by factor to convert to this unit. The name then works anywhere a unit symbol is accepted — in add_field (as the field's default unit), and in getvar(obj, var, name).
add_unit(:Msun_per_yr, 1.0) # e.g. for an SFR-like custom field
add_field(:mdot, (o,d)->d[:rho]; depends_on=[:rho], unit=:Msun_per_yr)See also delete_unit, list_units.
Mera.delete_unit — Function
delete_unit(name::Symbol)Remove a custom unit registered with add_unit.
Mera.list_units — Function
list_units() -> Vector{Symbol}The custom unit names registered with add_unit.
Mera.getvar_requirements — Function
getvar_requirements(kind::Symbol, vars) -> Vector{Symbol}The sorted set of physical stored variables that must be read to compute vars (a Symbol or a collection), with always-present geometry leaves (:cx/:cy/:cz, :level, :x/:y/:z, :cellsize, :volume, …) removed. Unknown/custom symbols are returned as-is (callers can detect these and fall back to reading everything).
getvar_requirements(:hydro, :ekin) # [:rho, :vx, :vy, :vz]
getvar_requirements(:hydro, [:sd, :T]) # [:rho, :p] (:sd is an alias of surface density → :rho)