Subregions cheatsheet

Everything subregion and shellregion can do, on one page. The Get Subregions tutorial shows each item working, step by step.

functioncuts
subregiona solid shape: box, cylinder or sphere. With a region value also a shell, and any combination of shapes
shellregiona hollow shell: spherical, or cylindrical (a ring of finite height)

Works the same on hydro, gravity and RT data. Particles, clumps and sinks are points; the rows below say where that changes something.

Two ways to write a region

region valueclassic symbol
callsubregion(gas, sphere(10.))subregion(gas, :sphere; radius=10.)
shellssubregion(gas, sphericalshell(10., 20.))shellregion(gas, :sphere; radius=[10., 20.])
default centrebox centre, [:bc]box corner, [0., 0., 0.]
default unit:kpc:standard (code units)
boundary cellssplit, with a :fraction per cellwhole cells (cell=true) or centre test (cell=false)
combine with ∩ ∪ \ !yesno
tilt (cylinder, cylindrical shell)yes, axis=[x, y, z]no, along z only
wrap at periodic facesnoyes, periodic=true

Use region values to measure. Use the classic form for quick looks, for periodic runs, and in older scripts.

subregion and shellregion

Both work on every data type and return the same type as their input. shellregion takes the same classic keywords as subregion: center, range_unit, cell, inverse, periodic, verbose and myargs. A shell can be cut three ways:

subregion(gas, sphericalshell(10., 20.))      # region value: boundary cells split
subregion(gas, sphere(20.) \ sphere(10.))     # the same shell as a difference, same sampling accuracy
shellregion(gas, :sphere; radius=[10., 20.],  # classic: whole cells or centre test
            center=[:bc], range_unit=:kpc)

The cylindrical shell in the same three forms:

subregion(gas, cylindricalshell(6., 10., 2.))                 # inner radius, outer radius, half-height
subregion(gas, cylinder(10., 2.) \ cylinder(6., 2.))
shellregion(gas, :cylinder; radius=[6., 10.], height=2., center=[:bc], range_unit=:kpc)

Shell rules

  • radius=[r_in, r_out]: inner radius first. In shellregion both must be larger than zero; for a full ball use a sphere.
  • height of a cylindrical shell is the half-height, as for the cylinder. The classic cylindrical shell runs along z only; cylindricalshell(…; axis=[x, y, z]) tilts it.
  • shellregion(obj) without a shape means :cylinder. Name the shape to be safe.
  • inverse=true selects everything outside the shell: the inside of r_in together with the outside of r_out.
  • A shell has two surfaces. With cell=true the classic shell keeps every cell that touches it, on both surfaces, like every other classic shape: its mass is an upper bound. With cell=false the centre test applies on both surfaces. sphericalshell and cylindricalshell split the cells of both surfaces.
  • Nested classic shells overlap with cell=true: neighbours share the cells on their common edge, so a radial profile from them counts those cells twice. Use cell=false (each cell goes to one shell) or region values (each cell is split between the shells).
  • A shell and the sphere (or cylinder) inside it share the inner surface. With region values their masses add up exactly to the mass of the outer sphere.
  • periodic=true works with shellregion, as with subregion.

Shapes

shaperegion valueclassic calltilt
boxcuboid(xrange=[a,b], yrange=[c,d], zrange=[e,f])subregion(obj, :cuboid; xrange=, yrange=, zrange=)no, aligned with the axes
cylindercylinder(r, h)subregion(obj, :cylinder; radius=r, height=h)region value: axis=[x, y, z]; classic: along z only
spheresphere(r)subregion(obj, :sphere; radius=r)not needed
spherical shellsphericalshell(r_in, r_out)shellregion(obj, :sphere; radius=[r_in, r_out])not needed
cylindrical shellcylindricalshell(r_in, r_out, h)shellregion(obj, :cylinder; radius=[r_in, r_out], height=h)region value: axis=[x, y, z]; classic: along z only
  • h is the half-height. cylinder(12., 2.) spans z from −2 to +2, so it is 4 kpc thick. The classic height= means the same.
  • Box ranges are measured from center. In the classic :cuboid, a range left out (or [0, 0]) means the full box along that axis.
  • Tilt. cylinder and cylindricalshell take axis=[x, y, z], any non-zero vector, and then run along that direction: a disc tilted like the galaxy, a bar in the disc plane, a ring seen at an angle. The axis also works inside combinations. A sphere and a spherical shell look the same in every direction, and the box is always aligned with the axes. The classic :cylinder and shellregion(:cylinder) run along z only; another direction is an error.
  • The classic :disc is another name for :cylinder.

Placing a region

center=means
[:bc] or [:boxcenter]the box centre
[x, y, z]a point, in range_unit, measured from the box corner
[13., :bc, :bc]mixed: x = 13, box centre in y and z
collect(center_of_mass(gas, :kpc))a point taken from the data

range_unit= is the unit of the centre and of every size: :kpc, :pc, :Mpc, :au, … or :standard for code units. info.scale lists them all.

A classic sphere, cylinder or shell without center sits on the box corner and keeps only the part inside the box. Mera prints a note once per shape when this happens.

Boundary cells

Only cell data (hydro, gravity, RT) have boundary cells. Particles, clumps and sinks are in or out.

treatmenthow to askthe mass you get
splitregion value, default split=trueexact, to the sampling accuracy of nsub
centre testsplit=false, or classic cell=falsean estimate; can be too high or too low
whole cellsclassic cell=true (the classic default)always too high: an upper bound

With split=true each kept cell carries :fraction ∈ (0, 1], the part of its volume inside the region.

keyword (region values)defaultdoes
nsub8points per axis used to measure the fraction of a cell cut by a curved surface. A box aligned with the axes is computed exactly
refine0replace boundary cells by their children, down to refine levels. Sharper edge in maps, same numbers
refine_tonothing[length, unit]: each boundary cell picks its own depth so its children are no larger than this. Set it to the map's pxsize. Not together with refine

The errors of whole cells and of the centre test grow with the size of the cells at the boundary. A small region, or one far from the refined gas, can be off by a large factor.

What the fraction scales

Quantities that say how much: :mass, :volume, and energies built from them. They are multiplied by the fraction in getvar, msum and projections. Quantities that say what the gas is like keep their value: density, temperature, velocity, potential. Details: Subregions API.

Inside and outside

callselects
subregion(obj, region; inverse=true)everything outside
shellregion(obj, :sphere; radius=[r_in, r_out], inverse=true)everything outside the shell
subregion(obj, !region)the same, written into the region
classic inverse=truethe same, for classic calls

The fractions flip (1 − fraction), so a region and its inverse add up to the whole box.

Combining regions

operatorASCII formfunctionselects
A ∩ BA & Bintersect(A, B)inside both
A ∪ BA | Bunion(A, B)inside at least one
A \ Bsetdiff(A, B)inside A, not inside B
!Aoutside A

Each part can have its own centre, and combinations nest freely. Type ∪ as \cup TAB and ∩ as \cap TAB.

shape = @region unit=:kpc center=[:bc] begin
    disc    = cylinder(12., 2.)
    blister = sphere(2.5; center=[30., :bc, 26.])     # an explicit keyword wins
    chimney = cylinder(1.2, 5.; center=[19., :bc, :bc])
    (disc ∪ blister) \ chimney
end
subregion(gas, shape)

Inside @region, every constructor that does not set center/range_unit gets the block's values. The result is an ordinary region.

Cutting a cut. subregion on an object that was already split multiplies the fractions. That is exact unless one cell is cut by both surfaces; Mera then prints a hint. For the exact result use subregion(obj, region1 ∩ region2).

Classic keywords

subregion(obj, :cuboid | :cylinder | :sphere;
          xrange, yrange, zrange,          # cuboid, measured from center
          radius, height,                  # cylinder (half-height), sphere
          center=[0., 0., 0.], range_unit=:standard,
          cell=true, inverse=false, periodic=false, verbose=true, myargs)

shellregion(obj, :cylinder | :sphere;
            radius=[r_in, r_out], height,  # height for the cylinder
            center=[0., 0., 0.], range_unit=:standard,
            cell=true, inverse=false, periodic=false, verbose=true, myargs)

myargs=ArgumentsType(...) passes a bundle of keywords at once, see Bundled Arguments. Radii and heights must be larger than zero.

Periodic boxes

periodic=truethe classic region wraps around all box faces
periodic=(x=true, y=true, z=false)wraps only some axes
cylinderswrap in their two radial directions, never along the height
region valuesnever wrap; they are clipped at the faces
info.boundaries:periodic, :nonperiodic or :unknown, read from the namelist

Mera never wraps on its own: RAMSES does not store the boundary conditions in its output. See Periodic Boxes for :r_sphere_periodic, center_of_mass(…; periodic=true) and periodic_recenter.

Data types

dataregion valuesclassicboundary
hydro, gravity, RTyesyessplit, centre test, or whole cells
particlesyesyespoint in or out
clumpsyesyespoint at the clump's peak position
sinksyesyespoint in or out

For points, cell= has no effect (cell=false prints a warning). split=true on RAMSES particles is an error: particles have no volume to split.

Gravity energies: cut the hydro object the same way

getvar(grav, gas, :total_binding_energy) and similar take their mass from the hydro object, so cut both with the same region: subregion(grav, R) and subregion(gas, R). Mera refuses a hydro object that was cut differently.

The result

  • The same type as the input: msum, getvar, projection, profile, savedata and another subregion work on it unchanged.
  • Mera.select(cut.data, :fraction) reads the fractions of a split cut.
  • Mera.get_filtered_ranges(cut) returns the bounding ranges of a classic cut, normalised to the box, ready for projection.
  • savedata(cut, path) stores a cut; loaddata reads it back. Cut before saving: loaddata reads the whole file.

Traps

  1. The cylinder height is a half-height. cylinder(r, 2.) is 4 units thick.
  2. The classic default centre is the box corner, and the classic default unit is code units.
  3. Region values do not wrap at periodic faces. Use the classic call with periodic=true.
  4. The centre test is not a bound. Only whole cells give a guaranteed upper limit, and only the split cut gives the measurement.
  5. Whole-cell regions that touch overlap. Neighbouring classic shells, or a classic sphere and the shell around it, share the cells on their common surface. For a budget or a profile, use region values or cell=false.
  6. A hole is hard to see in a projection through the whole box: the line of sight still passes the gas in front of and behind it. Limit the depth, e.g. zrange= of the region.
  7. A split edge looks soft in a map, because each cut cell is drawn over its full size. The numbers are right; use refine or refine_to for the picture.
  8. A cut of a cut multiplies the fractions. Combine the regions with ∩ for the exact joint fraction.
you want tosee
select by value: density, temperature, any getvar fieldMasking & Filtering, filterdata, getmask
distances in a periodic boxgetvar(obj, :r_sphere_periodic; center=…)
look along a tilted region's axisOff-axis projection
a uniform grid of a regionCovering Grid