The Particle Table#

A transport model run gives one table: a row per particle per output step. Everything after the run reads it: the footprint, the near-field correction, the transforms, the plots, and the particle files in the output directory. sim.particles and stilt.run_trajectories() return it as a pandas DataFrame. Output Layout says how a particle file stores it.

Every table has five columns, PARTICLE_SCHEMA:

Column

Units

Meaning

particle

none

Particle number, from 1 to numpar. A particle keeps its number for the whole run. HYSPLIT and STILT-R call it indx. Stored as int32 and read back as float64.

age

minutes

Time since release. Negative for a backward run, positive for a forward one. HYSPLIT and STILT-R call it time. Stored as whole minutes, int32, and read back as float64.

lon

degrees east

Longitude of the particle (HYSPLIT’s long).

lat

degrees north

Latitude of the particle (HYSPLIT’s lati).

zagl

m

Height of the particle above ground.

A footprint also needs foot:

foot

The particle’s sensitivity to surface fluxes accumulated over the output step, in ppm per (µmol m⁻² s⁻¹). It is zero while the particle is above veght of the mixed layer (or veght meters when that is more than 1). HYSPLIT computes it as STILT-R does: the time the particle spent in that surface layer, divided by the air density and the depth the flux is mixed through. stilt.calc_footprint() adds each particle’s foot into its grid cell and divides by the number of particles.

The release row#

A model should write each particle’s release as a row at age = 0, with foot = 0: a positive foot there would add a layer at hour 0 to the footprint. That row is where the particle started, so it says which release point of a multipoint receptor the particle left from, and which slab of a column receptor (add_release_heights()). The HYSPLIT build bundled with PYSTILT writes no such row: its first row is one time step after release. For it, PYSTILT matches each particle to a release point from its first position, and takes a column’s particles to be released bottom to top in particle order. A HYSPLIT build patched to write the release rows (exe_dir) makes the matching exact.

Columns the model adds#

HYSPLIT writes the variables in varsiwant under HYSPLIT’s lowercase four-letter names, except indx, time, long, and lati, which become the columns above. The allowed names are listed under varsiwant in Configuration; the config refuses any other name when it is read. Some that PYSTILT reads:

Column

Units

Meaning

mlht

m

Mixed-layer height above ground.

dens

kg m⁻³

Air density.

samt

minutes

Time the particle spent in the surface layer during the step.

sigw

m s⁻¹

Standard deviation of the vertical wind.

tlgr

s

Lagrangian time scale.

pres

hPa

Pressure, for pressure weighting.

zsfc

m

Terrain height above sea level. It is not in the default varsiwant. Add it for a receptor given above sea level (altitude_ref="msl"): pressure weighting raises without it, and the near-field correction is skipped without it.

zcfx

m

Vertical displacement by convective flux along the trajectory, summed over the steps (the Grell scheme, capemin: -2). HYSPLIT reads this name only: zfx1 stops it, and the config refuses it.

The near-field correction reads dens, samt, sigw, tlgr, foot, and mlht (HNF_PLUME_COLUMNS). The plume it models grows from the release height above ground, so for a receptor above sea level it also reads zsfc. Without it the run’s log says the correction was skipped.

mlht, dens, pres, and zsfc can also be sampled from the met files at each particle’s position, for a model that writes only positions: stilt.sampling.sample_met(). The values are the met’s, so they differ from HYSPLIT’s own columns; Meteorology says by how much.

Columns PYSTILT adds#

release_height

Release height of each particle, in meters in the receptor’s own vertical reference, for column and multipoint receptors (add_release_heights()). For a column it is the center of the particle’s slab, the part of the column the particle stands for. STILT-R and X-STILT call it xhgt.

foot_no_hnf_dilution

foot before the near-field correction (correct_near_field()), when hnf_plume is on.

time

The time of each row, in UTC: the receptor time plus age, added when the table is read from a file. STILT-R’s time is age here.

Checking a table#

PARTICLE_SCHEMA

The columns every particle table has, as a particle file stores them: what a transport model's run must return.

FOOTPRINT_COLUMNS

The column a footprint is made from.

HNF_PLUME_COLUMNS

Particle columns the near-field plume correction reads (varsiwant must include them).

check_particles

Check that a particle table has the columns of PARTICLE_SCHEMA, and need.

After a run#

PYSTILT adds the release heights to any model’s particles, and applies the near-field correction when hnf_plume is set. A model whose particles lack the columns the correction reads gets none, and a warning says so.

add_release_heights

Return particles with each particle's release_height, for a column or multipoint receptor.

correct_near_field

Correct foot for plume dilution in the hyper-near field, as STILT-R's calc_plume_dilution does.