Projections: which tool

Mera has more than one way to turn a simulation into a picture, and the names do not say which is which. This page is a router: find the sentence that matches what you want, and follow it.

Everything here works the same on hydro and, unless noted, on particles.

A single map

I wantUse
a map along a box axisprojection(gas, :sd; direction=:z), see Hydro / Particles
a galaxy face-on or edge-onprojection(gas, :sd; direction=:faceon), which derives the orientation from the data's own angular momentum. No preparation step needed
any other viewing angleinclination/azimuth about a reference axis, or an explicit los=[x,y,z], see Off-axis
the disc's axis as a value I can reuseface_on / edge_on, which return a frame whose los/up/center splat into any later call
the same window at every anglefov/fov_unit with `aperture=:circle

Selecting a region first

subregion and shellregion work on all six data types, including RT and sinks, which have no tutorial page of their own. One trap, documented in the Subregions API: neither function wraps at a periodic boundary, so a region near a box face is silently clipped rather than wrapped.

A cutting plane

A plane, not a column: values at a depth rather than integrated through it.

I wantUse
a plane along a box axisslice(gas, :rho; slice_axis=:z, slice_pos=0.5), see Covering grid
a tilted planeslice(gas, :rho; inclination=…), the same view keywords as projection
the plane to travel through the objectoffset/offset_unit, which slides it along the line of sight
the same for particlesyou want thickness, not a plane, see below

Particles have no cutting plane, and that is not an omission. A particle is a point, so a zero-thickness plane through a particle cloud is empty by construction. The useful analogue is a projection of finite depth: projection(part, :sd; thickness=2, thickness_unit=:kpc) integrates a slab instead of the whole column, and offset moves the slab. Asking for zero thickness is refused rather than returning an empty map.

A movie

Three different movies, and the difference is what changes between frames.

Between frames, what changes?Use
time, one frame per snapshotgetmovie(path, :sd)
angle, one snapshot seen from many sidesrotation_sequence, which fixes the frame so the object cannot drift
both: a full turn at each snapshotgetmovie(…; angles=0:5:355), giving outputs × angles frames
both: turning while the run evolvesgetmovie(…; sweep=(0, 180)), one frame per snapshot at a moving angle

No frame is ever interpolated: each is a real projection from a real viewpoint.

Two things worth knowing before a long render. Pass fov for any off-axis movie, or the frame refits per snapshot and the movie breathes. And angles keeps a snapshot in memory while its viewpoints render, which is the one place getmovie gives up its one-snapshot-at-a-time frugality; sweep does not.

Particle movies work: getmovie(path, :sd; datatype=:particles). Gravity and clumps cannot be projected on their own, and say so.

Why there are two engines

direction=:x/:y/:z and the off-axis path are separate implementations, and the reason is geometric rather than historical.

Seen down a box axis, a cell's shadow on the image plane is an axis-aligned rectangle, and the overlap with a pixel is a product of two independent 1-D overlaps. That is what the axis-aligned engine exploits: it bins in integer grid-index space, per refinement level, which is both exact and fast.

Rotate the camera and the same cube casts a hexagon, because you now see three of its faces. The overlap stops being separable and becomes an integral over a piecewise-linear height field, and that is a different algorithm, the one binning=:overlap/:exact implement. It degenerates correctly to the axis-aligned case when the line of sight is parallel to a box axis.

The practical consequences:

  • the axis-aligned path is faster, and populates maps_lmax
  • a few map-only quantities (:σx, :σy, :σz and the radius/angle family) exist only there, and an off-axis call asking for them is rejected with an error rather than a wrong answer
  • the off-axis path has fov/aperture framing, which the axis-aligned one does not need

Particles need no such split: their deposition kernels are rotation-invariant, so the same code serves both.

Where the detail lives

  • Off-axis Projection, the full treatment: camera, framing, accuracy, kinematics, slices, orbit movies, and what works on which data type
  • Hydro and Particles, the axis-aligned tutorials
  • Pipelines, projecting several quantities in one line and reusing one selection across loading and projection
  • Auto-Frame, finding an object's own orientation
  • Movies, assembling and writing them
  • projection() with no arguments prints the whole keyword surface, which is the fastest way to find a keyword whose name you do not yet know