Output and visualization API
Output defines snapshot capture and persistence, and observation sampling ([output.observations]: point events and station series sampled at met-window ends). Visualization provides topology-aware field views and optional Makie rendering for those snapshots.
Output
AtmosTransport.Output Module
OutputTopology-aware diagnostic output for AtmosTransport runtime products.
This module owns the public NetCDF output contract. Runtime code should capture model state with capture_snapshot and write files with write_snapshot_netcdf instead of defining ad-hoc NetCDF layouts in runner code.
The writer is intentionally topology-dispatched:
LatLonMeshwrites regular CF lon/lat coordinates.ReducedGaussianMeshwrites native cell-indexed diagnostics plus a legacy lon/lat raster view for current debug plots.CubedSphereMeshwrites panel-native diagnostics with GEOS-stylelons,lats,corner_lons,corner_lats,cell_area, andcubed_spheremetadata so Panoply and downstream tools have enough geometry context to render C-grid snapshots.
New topologies should add methods for the small internal schema/diagnostic functions in this folder; they should not special-case the runner.
Output also owns observation sampling (observations/): the [output.observations] contract, source readers, containing-cell locators, the device column gather, and the append-only _soundings / _sites NetCDF files written by build_observation_sampler's sampler.
AtmosTransport.Output.VERTICAL_PLACEMENT_CODES Constant
Integer vertical_placement codes of the observation files, the method that placed each request (see vertical_placement_codes_description):
| Code | Name | Layer chosen by |
|---|---|---|
| 0 | record_height | the record's height above ground (intake_height, or altitude − elevation) |
| 1 | altitude_minus_dem | altitude − DEM ground elevation at the point |
| 2 | pressure | the record's pressure against the interface pressures of the pressure_basis (total by default) |
| 3 | absolute_altitude | altitude against model surface height + layer heights (absolute_altitude_above_agl_m) |
| 4 | lowest_layer | no vertical coordinate, for sources whose records are column or surface products |
AtmosTransport.Output.AboveGroundPlacement Type
Every record at its height above the ground, measured up from the model surface (default).
sourceAtmosTransport.Output.AbsoluteAltitudeAbove Type
AbsoluteAltitudeAbove(min_height_agl_m)absolute_altitude_above_agl_m = h: records at least h m above the ground (free-tropospheric aircraft and AirCore samples) are placed by their pressure when the record has one, else by their altitude above sea level against the model's geopotential heights (model surface height plus layer heights). The altitude is the record's altitude, else its ground elevation (the record's, else the DEM's) plus its intake_height; a record with neither keeps its height above the ground. Records below h keep AboveGroundPlacement. Needs a model surface height (surface_height_file).
AtmosTransport.Output.AbstractAltitudePlacement Type
How records that carry an altitude are placed once their height above the ground is known.
sourceAtmosTransport.Output.AbstractAveragingKernelOutput Type
AbstractAveragingKernelOutputWhether an OCO-2 source's soundings also get the averaging-kernel column of the sampled model profile: NoAveragingKernels (the default) or AveragingKernelColumns.
AtmosTransport.Output.AbstractMissingHeightRule Type
AbstractMissingHeightRuleWhat a source's records mean when they give no vertical coordinate at all (no intake_height, altitude or pressure), chosen by the source type (missing_height_rule): LowestLayerWithoutHeight or UnplacedWithoutHeight.
AtmosTransport.Output.AbstractModelSurfaceHeight Type
AbstractModelSurfaceHeightSurface height of the model grid (m above sea level): the ground the model's layer heights are measured from. NoModelSurfaceHeight (default) or ModelSurfaceHeight, read from a per-grid dataset by GriddedIO.read_model_surface_height. Query it with model_surface_height.
AtmosTransport.Output.AbstractObservationOutput Type
Parsed [output.observations]: either NoObservationOutput or a spec.
AtmosTransport.Output.AbstractObservationSource Type
AbstractObservationSourceWhere sampling requests come from. Concrete sources carry a path template ({YYYYMMDD} or {date}, {YYMMDD}, {YYYY}, {MM}, {DD} substituted per run day; * and ? wildcards in the file name) and declare whether they yield point events (SoundingMode) or station series (SiteMode).
AtmosTransport.Output.AbstractObservationTimeInterpolation Type
How point events are placed in time between met-window ends.
sourceAtmosTransport.Output.AbstractPointElevation Type
AbstractPointElevationGround elevation (m above sea level) at a point, from a high-resolution digital elevation model: NoPointElevation (default) or GriddedIO.LatLonPointElevation (GriddedIO.read_point_elevation). Query it with point_elevation.
AtmosTransport.Output.AbstractPressureBasis Type
AbstractPressureBasisThe vertical basis of a column's placement (pressure_basis), one choice for the interface pressures a pressure-placed record (or an averaging-kernel column) is compared with and for the hypsometric layer heights a record placed by height is compared with: TotalFromHumidity (default) or DryInterfaces. A record's pressure is the total (ambient) pressure, dry air plus water vapour. The air mass of a dry-basis run gives dry interface pressures,
AtmosTransport.Output.AbstractRetrievalMapping Type
AbstractRetrievalMappingHow the profile values of a retrieval relate to its pressures, and so how the model column is mapped onto them (the projection matrix retrieval_column_weights!): LayerRebin (values are layer means between interfaces) or HatLevelProjection (values on levels, the profile linear in pressure between them). A RetrievalColumn carries one; the operator dispatches on it.
AtmosTransport.Output.AbstractSiteSchedule Type
AbstractSiteScheduleWhen a station is sampled. Chosen per site from the site table:
| Table keys | Type | Output |
|---|---|---|
| none | EveryWindow | every met-window end, _sites file |
start_time, end_time | TimeRange | every met-window end inside the range, _sites file (NaN outside) |
times | TimeList | one point event per listed UTC time, _soundings file |
AtmosTransport.Output.AbstractUnplacedPolicy Type
What the sampler does with requests it cannot place in the column.
sourceAtmosTransport.Output.AbstractVerticalCoordinate Type
AbstractVerticalCoordinateA vertical coordinate that can place a record in the model column: HeightAboveGroundCoordinate or PressureCoordinate. VerticalPlacementSpec lists the coordinates a run uses in preference order (vertical_coordinates); resolve_placement places each record by the first one it can.
AtmosTransport.Output.AutoTableFormat Type
Derive the format from the file extension (.csv, .toml, .nc/.nc4).
AtmosTransport.Output.AveragingKernelColumns Type
AveragingKernelColumns(tracers, mapping = HatLevelProjection())averaging_kernel_tracers = [...] on an oco2_lite source: the reader also reads each sounding's retrieval (levels, pressure weights, averaging kernel, prior, prior column; read_oco2_retrieval_columns), and the sampler writes, for each tracer of tracers, the averaging-kernel column <tracer>_ak_column, with the operator of the 4D-Var (retrieval_column_weights!). mapping (averaging_kernel_mapping) is HatLevelProjection ("hat", the levels as given) or LayerRebin ("tm5", TM5-4DVar's 19 layers, tm5_layer_column). The prior term belongs to the retrieved gas, so name the tracer that carries it (total CO2), not components of it.
AtmosTransport.Output.CSVTableFormat Type
Comma-separated with a header line; # comments; no quoting. List-valued times use ;.
AtmosTransport.Output.DryInterfaces Type
pressure_basis = "dry": compare a record's pressure with the dry interface pressures
AtmosTransport.Output.ErrorOnUnplaced Type
unplaced_records = "error" (default): building the sampler fails, naming the requests.
AtmosTransport.Output.HatLevelProjection Type
HatLevelProjection()Retrieval values sit on N levels and the profile is linear in pressure between them: the OCO-2 and OCO-3 retrievals (20 levels, "defined on layer boundaries", the first at
so retrieval_mapping = "hat_levels".
AtmosTransport.Output.HeightAboveGroundCoordinate Type
"height_above_ground": the record's height intake_height, else altitude − elevation, else altitude minus the DEM ground elevation at the point, measured up from the model surface with the model's hypsometric layer heights (vertical_placement codes record_height and altitude_minus_dem).
AtmosTransport.Output.LayerRebin Type
LayerRebin()Retrieval values are means over N layers between N + 1 interfaces (a TCCON or GOSAT layer grid, TM5-4DVar's 19-layer form of OCO-2, tm5_layer_column). The model column, stretched onto the retrieval column, is rebinned by pressure overlap: inv_rebin (retrieval_rebin_matrix). Stored as retrieval_mapping = "layer_rebin".
AtmosTransport.Output.LinearWindowInterpolation Type
Blend the two met-window-end samples bracketing each sounding time (default).
sourceAtmosTransport.Output.LocationGrouping Type
One site per distinct (lat, lon, intake height) rounded to 0.01° and 0.1 m, with ids <site_code>_<lat>N_<lon>E_<h>magl in signed decimal degrees.
AtmosTransport.Output.LowestLayerWithoutHeight Type
The record is a column or surface product: it is sampled in the lowest layer (vertical_placement = lowest_layer). OCO-2 soundings (their value is the column; the intake value is the surface layer) and table rows without height columns (surface points).
AtmosTransport.Output.ModelSurfaceHeight Type
ModelSurfaceHeight(field, path)Per-cell surface height of the model grid (m above sea level), in the mesh's native layout: an (Nx, Ny) matrix on a lat-lon mesh, a vector over the cells on a reduced Gaussian mesh, a 6-tuple of (Nc, Nc) panels on the cubed sphere. path is the per-grid dataset it came from (written to the observation files as provenance).
AtmosTransport.Output.NearestWindowSampling Type
Use the single met-window-end sample nearest to each sounding time.
sourceAtmosTransport.Output.NetCDFTableFormat Type
One-dimensional NetCDF variables along the record dimension; CF time units.
AtmosTransport.Output.NoAveragingKernels Type
No averaging-kernel columns (the default): the reader reads no retrieval fields.
sourceAtmosTransport.Output.NoModelSurfaceHeight Type
No model surface height configured; model_surface_height returns NaN.
AtmosTransport.Output.NoObservationOutput Type
Default when [output.observations] is absent or enabled = false.
AtmosTransport.Output.NoObservationSampler Type
No-op sampler installed when observation output is absent or disabled.
sourceAtmosTransport.Output.NoQualityFilter Type
quality_filter = "none": keep every record (the OCO-2 v11 MIP co-samples all 10-s averages).
AtmosTransport.Output.OCO2LiteSource Type
OCO2LiteSource(path_template, quality_filter[, averaging_kernel = NoAveragingKernels()])NASA OCO-2/OCO-3 Lite XCO2 files, or the OCO-2 v11 MIP 10-second average files (same sounding_id, time, latitude, longitude layout). Records passing quality_filter become point events. With averaging_kernel = AveragingKernelColumns(tracers) (opt-in) the reader also reads each record's retrieval and the sampler writes averaging-kernel columns of the named tracers (AveragingKernelColumns).
AtmosTransport.Output.ObsPackSource Type
ObsPackSource(path_template, mode, site_grouping)NOAA ObsPack NetCDF dataset files. SiteMode() groups records into fixed stations by site_grouping; SoundingMode() samples every record at its own time.
AtmosTransport.Output.ObservationOutputSpec Type
ObservationOutputSpecParsed [output.observations] table. path is a template: _soundings or _sites is inserted before the extension and, with daily partitions, {date} / {YYYYMMDD} / {day} are substituted per input binary exactly as for snapshot output. tracers === nothing means every model tracer. start_time is only consulted when [input].start_date is absent. placement is the VerticalPlacementSpec.
AtmosTransport.Output.ObservationSet Type
ObservationSet(origin, soundings, sites[, dropped_outside_window, skipped_invalid])Every sampling request of a run. build_observation_set sorts soundings by time_seconds (stable) and merges sites so they are unique by id; the constructor itself neither sorts nor deduplicates, and only rejects site series with a TimeList schedule. dropped_outside_window counts the point events outside the transported span; skipped_invalid counts source rows skipped for fill values, invalid coordinates, or the quality filter.
AtmosTransport.Output.ObservationTerrain Type
ObservationTerrain(; model_surface = NoModelSurfaceHeight(), dem = NoPointElevation())The static ground fields observation placement may use: the model-grid surface height (AbstractModelSurfaceHeight) and a point DEM (AbstractPointElevation). The runner builds it from [output.observations] through GriddedIO and passes it to build_observation_sampler.
AtmosTransport.Output.PlacementColumn Type
PlacementColumn(nlevel)Scratch for column_layer! and sample_column_layer! on a column of nlevel layers: p_half receives the interface pressures of the pressure basis (those a pressure placement is compared with, and the total pressures of the heights), and humidity holds the column's specific humidity (k = 1 at the top), which the caller fills when the pressure basis needs it (needs_column_humidity).
AtmosTransport.Output.PressureCoordinate Type
"pressure": the record's pressure (ObsPack pressure, a total pressure) against the column's interface pressures, built as the AbstractPressureBasis says (vertical_placement code pressure).
AtmosTransport.Output.QualityFlagFilter Type
QualityFlagFilter(variable, max)quality_filter = "flag_max": keep records whose integer flag variable is <= max (Lite files: xco2_quality_flag, 0 = good).
AtmosTransport.Output.RetrievalColumn Type
RetrievalColumn(pressure_pa, pressure_weight, averaging_kernel, prior_profile,
profile_sigma, surface_pressure_pa[, mapping = LayerRebin()[, prior_column = NaN]])
RetrievalColumn(; pressure_pa, pressure_weight, averaging_kernel, prior_profile,
profile_sigma = Float64[], surface_pressure_pa = first(pressure_pa),
mapping = LayerRebin(), prior_column = NaN)The vertical description of one retrieved column average (a satellite or TCCON sounding) with N retrieval values, ordered from the surface up. The mapping (AbstractRetrievalMapping) says what the values are:
LayerRebin: means overNlayers;pressure_paholds theN + 1layer interfaces;HatLevelProjection: values onN ≥ 2levels, the profile linear in pressure between them (OCO-2/OCO-3);pressure_paholds theNlevel pressures.
Fields:
pressure_pa: the interfaces or levels (Pa, total pressure), surface first, strictly decreasing; the last is the retrieval top (≥ 0);pressure_weight: the pressure weights( N,≥ 0, summing to 1 withinRETRIEVAL_WEIGHT_SUM_TOLERANCE);averaging_kernel: the column averaging kernel( N, normalized, dimensionless:); prior_profile: the retrieval prior( N, dry mole fraction, mol mol⁻¹, in[0, 1]);profile_sigma: optional 1-σ uncertaintyof the model profile on the retrieval layers or levels ( N, mol mol⁻¹, in[0, 1]; empty when absent), the input of the model-error termretrieval_model_error_variance. It is not the retrieval's a-priori uncertainty: the smoothing error is already represented by the averaging kernel;surface_pressure_pa: the retrieval surface pressure (Pa), equal to the first pressure (relative tolerance 1e-6);mapping: theAbstractRetrievalMapping;prior_column: optional, the retrieval's prior column(mol mol⁻¹, in [0, 1];NaNwhen absent), e.g. the OCO-2xco2_apriori. When given, the column is(the MIP protocol's eq. 2); without it . The two differ when the weights and the prior were averaged separately (OCO-2 10-s averages: a few thousandths of a ppm).
Every value but an absent prior_column must be finite. See retrieval_column_weights! for the operator.
AtmosTransport.Output.RuntimeOutputMetadata Type
Metadata resolved from the typed physics objects of one runtime invocation.
sourceAtmosTransport.Output.SelectedSnapshotFrame Type
SelectedSnapshotFrameCPU-resident output containing only requested levels and column reductions. nlevel preserves the original vertical coordinate. levels maps stored layers back to model levels; column sums are computed before selecting layers. Tracer storage is VMR × air mass, with no molecular-weight conversion.
AtmosTransport.Output.SiteCodeGrouping Type
One site per dataset file and distinct intake height. The id is the dataset name (ObsPack files already encode site, platform, and lab), suffixed with _<h>magl only when a file holds several intake heights.
AtmosTransport.Output.SiteRequest Type
SiteRequest(id, lon, lat, elevation_m, intake_height_m, source[, schedule[, altitude_m]])A fixed station. The vertical fields have the meaning of those of SoundingRequest (NaN when unknown; a station has no pressure); the sampler turns them into a VerticalPlacement when it is built. schedule defaults to EveryWindow.
AtmosTransport.Output.SkipUnplaced Type
unplaced_records = "skip": such requests are dropped and counted (n_unplaced_* attributes).
AtmosTransport.Output.SnapshotFrame Type
SnapshotFrameCPU-resident snapshot of one model state at one output time.
air_mass and each entry in tracers keep the topology-native storage shape:
LL:
(lon, lat, lev)RG:
(cell, lev)CS:
NTuple{6, Array{T, 3}}with panel interiors(Xdim, Ydim, lev)
Tracer arrays store the model's conservative χ × carrier-air-mass quantity, not mixing ratio or physical kg species. Derived VMR and column diagnostics are computed by write_snapshot_netcdf. tracer_total_mass stores a compensated Float64 sum of that conservative quantity for every tracer. It is kept separately so Float32 visualization payloads cannot degrade global signed mass diagnostics through cancellation or output conversion.
Snapshot storage must be CPU-resident. Use capture_snapshot for model state on any backend; it strips cubed-sphere halos and copies device arrays to the host before constructing the frame.
AtmosTransport.Output.SnapshotWriteOptions Type
SnapshotWriteOptions(; float_type=Float32, deflate_level=0, shuffle=true)Options controlling NetCDF snapshot output.
float_typeis the on-disk type for heavy diagnostic variables.deflate_levelis the NetCDF compression level for heavy payload variables:0disables compression,1is fast/light, and9is maximum compression.shuffleenables the NetCDF shuffle filter when compression is active.
AtmosTransport.Output.SoundingMode Type
Time-stamped point events; each record is sampled at its own time.
sourceAtmosTransport.Output.SoundingRequest Type
SoundingRequest(id, time_seconds, lon, lat, source[, elevation_m, intake_height_m[, altitude_m, pressure_pa[,
retrieval]]])One point event, sampled at time_seconds after the run origin (Float64 UTC seconds). source indexes the spec's sources. The vertical fields are what the record says about its height, NaN when it says nothing: intake_height_m (m above the ground: the record's intake height, or its altitude minus its elevation), altitude_m (m above sea level), elevation_m (ground, m above sea level) and pressure_pa (Pa). The sampler turns them into a VerticalPlacement once, when it is built (resolve_placement). retrieval is the sounding's RetrievalColumn when its source asks for averaging-kernel columns (AveragingKernelColumns), else nothing.
AtmosTransport.Output.TOMLTableFormat Type
[[soundings]] or [[sites]] arrays of tables; times may be a TOML array.
AtmosTransport.Output.TableSource Type
TableSource(path_template, mode, format)Generic point list as CSV, TOML, or NetCDF. Point events need id, time (ISO-8601 UTC), lat, lon; sites need id, lat, lon. Both accept elevation (m asl) and intake_height (m above ground) or altitude (m asl, converted with elevation, else placed by resolve_placement). Sites may add start_time/end_time (TimeRange) or times (TimeList).
AtmosTransport.Output.TimeList Type
TimeList(times_seconds)Sample the site once at each listed time (seconds after the run origin), like a sounding: blended between the bracketing met-window ends and written to the _soundings file with the intake-layer value.
AtmosTransport.Output.TimeRange Type
TimeRange(start_seconds, stop_seconds)Sample the site at every met-window end with start <= t <= stop (seconds after the run origin); records outside the range are written as NaN.
AtmosTransport.Output.TotalFromHumidity Type
pressure_basis = "total" (default): compare a record's pressure with the column's total interface pressures, and a record's height with the hypsometric heights of moist air on them. Specific humidity
with VIRTUAL_TEMPERATURE_FACTOR, 0.61) and A_ifc[1], a total pressure in the met model's hybrid coordinate (level 1 is the top). This inverts the preprocessing's dry conversion pre_ll72 binary (ERA5 L137 merged to 34 levels) the rebuilt total surface pressure differs from the stored one by −0.012 Pa on average and 0.125 Pa at most, where the dry interfaces are 169 Pa low on average and 700 Pa at worst. The humidity is the binary's layer-mean specific humidity at the sampled boundary: qv_start / qv_end of lat-lon binaries preprocessed with output.include_qv = true; on cubed-sphere binaries with the GCHP VDIFF payload the window-start VDIFF qv of the next window (the run's last window end takes the ended window's, one window old). Reduced-Gaussian binaries, and cubed-sphere binaries without the VDIFF payload, carry no humidity. On a moist-basis run the air mass already includes the vapour and its interfaces are total pressures without humidity; the heights there use pressure_basis = "dry".
AtmosTransport.Output.UnplacedWithoutHeight Type
The record should state a height and does not: it cannot be placed (unplaced_records). ObsPack records, where every platform carries a height.
AtmosTransport.Output.VerticalPlacement Type
VerticalPlacement(method, height_agl_m, pressure_pa, model_surface_m)How one request is placed in the column, resolved once by resolve_placement: method is a VERTICAL_PLACEMENT_CODES code; height_agl_m the height above the model surface that selects the layer (NaN for pressure and lowest-layer placement); pressure_pa the pressure that selects it (pressure placement only); model_surface_m the model surface height of the cell (NaN without a surface-height dataset).
AtmosTransport.Output.VerticalPlacementSpec Type
VerticalPlacementSpec(; surface_height_file = nothing, dem_file = nothing, dem_variable = "z",
unplaced = ErrorOnUnplaced(), altitude_placement = AboveGroundPlacement(),
coordinates = DEFAULT_VERTICAL_COORDINATES,
pressure_basis = TotalFromHumidity())The vertical-placement settings of [output.observations]: the per-grid model surface height dataset, an optional point DEM (file and variable), the AbstractUnplacedPolicy, the AbstractAltitudePlacement, the AbstractVerticalCoordinates in preference order (a non-empty tuple without repeats; by default height above ground, then pressure), and the AbstractPressureBasis of pressure placement.
AtmosTransport.Output.begin_observation_day! Method
begin_observation_day!(sampler, date_label, day_index)Called by the runner before the first window boundary of each input binary. Single-file runs open their files on the first call; daily runs close the previous day's files and open the next pair. Rows are written to the files open at emission time. A binary's last window ends at the next day's 00:00, which is still observed before the next binary opens: with linear interpolation a sounding lands in the file of its own day, and each day's sites file ends with the 00:00 sample of the next day (the first file also holds the initial state at t = 0). With nearest_window, soundings in the first half window after 00:00 are emitted at that boundary and land in the previous day's file.
AtmosTransport.Output.build_observation_sampler Method
build_observation_sampler(spec, state, grid; origin, window_seconds, halo_width,
terrain = ObservationTerrain(), has_humidity = false)Read every source for the days covering window_seconds (seconds after origin, half-open), locate the requests on grid.horizontal, place each in the column (resolve_placement with the static ground fields of terrain, see ObservationTerrain), and prepare the device gather buffers. Requests that cannot be placed fail the build or are skipped and counted, as spec.placement.unplaced says. has_humidity says whether the run's binaries carry specific humidity: on a dry-basis run every request needs it for the total interface pressures and the virtual-temperature layer heights of TotalFromHumidity (the default spec.placement.pressure_basis; check_pressure_basis), and the build fails without it unless the basis is DryInterfaces; every window end must then pass humidity to observe_window_boundary!. Output files are opened by begin_observation_day!. NoObservationOutput yields NoObservationSampler().
AtmosTransport.Output.build_observation_set Method
build_observation_set(sources, origin, window_seconds) -> ObservationSet
build_observation_set(sources, origin, dates)Read every source for the days covering the window, merge sites by id, expand site time lists into point events, keep the point events with window_seconds[1] <= t <= window_seconds[2] (seconds after origin; the dates form uses whole days), and sort them by time (stable). A site id that repeats (across rows, daily files, or sources) must keep its location; time lists of a repeated id are merged, and other schedules must be equal. Per-source counts are logged.
AtmosTransport.Output.capture_snapshot Method
capture_snapshot(model; time_hours=0, halo_width=0, fields=nothing)Capture air-mass and conservative tracer-storage fields from a TransportModel. Without fields, return a full SnapshotFrame. Passing an OutputFieldSpec returns a SelectedSnapshotFrame containing only requested layers and column diagnostics, plus compensated Float64 totals for the selected tracers.
The result is CPU-resident and topology-native. For cubed-sphere states, halo_width strips panel halos before writing. GPU-backed arrays are copied to host memory by Array(...).
AtmosTransport.Output.column_layer! Method
column_layer!(column::PlacementColumn, placement, z_half, air_column, area, g, p_top, basis, mass_basis) -> IntModel layer (k = 1 top) of a VerticalPlacement in one column, the rule shared by the forward sampler and any other caller: by height above the model surface on the hypsometric interface heights z_half, or the lowest layer (as placement_layer); a pressure placement against the interface pressures of the AbstractPressureBasis basis, built into column.p_half from air_column (kg per cell, of mass_basis), the cell area (m²), gravity g, the model-top pressure p_top and, for TotalFromHumidity on a dry basis, column.humidity.
AtmosTransport.Output.column_mass_per_area Method
column_mass_per_area(field, mesh)Vertically integrate per-cell mass and divide by horizontal cell area.
sourceAtmosTransport.Output.column_mean_mixing_ratio Method
column_mean_mixing_ratio(air_mass, tracer_storage)Compute the air-mass-weighted vertical mean mixing ratio for one snapshot field.
The returned shape is topology-native horizontal storage:
LL:
(lon, lat)RG:
(cell,)CS:
NTuple{6, Matrix{Float64}}
AtmosTransport.Output.define_cs_horizontal_geometry! Method
define_cs_horizontal_geometry!(ds, mesh::CubedSphereMesh) -> nothingDefine the horizontal geometry of a panel-native cubed-sphere NetCDF file in the open dataset ds: the GEOS-style layout shared by runtime snapshots and cs_native input files. Vertical and time axes are not defined here; each writer owns those.
Dimensions Xdim, Ydim (Nc), Xcorner, Ycorner (Nc + 1) and nf (6). Variables (coordinates and geometry in Float64 whatever the mesh precision):
Xdim,Ydim: panel indices1:Nc, taggeddegrees_east/degrees_north("Fake Longitude/Latitude for GrADS Compatibility", the GEOS-Chem convention) so Panoply and GrADS render a per-panel map;nf(Int32): panel1:6.lons,lats(Xdim, Ydim, nf): cell-centre longitude and latitude [degrees], frompanel_cell_center_lonlatin the mesh's panel convention.corner_lons,corner_lats(Xcorner, Ycorner, nf): cell corners [degrees], frompanel_cell_corner_lonlat.cell_area(Xdim, Ydim, nf)[m²]: the mesh's own cell areas (the areas the runtime multiplies fluxes by), withcoordinates = "lons lats".cubed_sphere(scalar Int32): grid mapping withgrid_mapping_name,cs_definition,cs_coordinate_law,cs_center_law,panel_convention,longitude_of_central_meridian,semi_major_axis = mesh.radius[m] andinverse_flattening = 0. Panel data variables point at it withgrid_mapping = "cubed_sphere"andcoordinates = "lons lats".
The same definition tags are also written as global attributes (Nc, cs_definition, cs_coordinate_law, cs_center_law, panel_convention, grid_mapping_name, longitude_of_central_meridian); readers rebuild the mesh from them.
AtmosTransport.Output.define_provenance_attributes! Method
define_provenance_attributes!(ds) -> (; creation_date, git_commit, git_dirty)Write the automated provenance block shared by every NetCDF file AtmosTransport writes (snapshots, observation files, and generated input files) as global attributes of the open dataset ds:
| Attribute | Value |
|---|---|
creation_date | write time, ISO 8601 UTC with a Z suffix |
framework | "AtmosTransport.jl" |
framework_commit | commit of the source tree (AtmosTransport.source_revision()) |
framework_dirty | "clean", "dirty" or "unknown" |
runtime | Julia version, machine triple and operating system |
hostname, user | host name and USER (or USERNAME) |
Every value is best-effort and falls back to "unknown" instead of throwing, so a tree without git still produces a complete block. Returns the creation date and the source-tree state so the caller can compose its history line.
AtmosTransport.Output.finish_observations! Method
finish_observations!(sampler)Emit events exactly at the final window end, drop events that never received their second sample, write the summary attributes, and warn about anything that was not sampled. Idempotent.
sourceAtmosTransport.Output.layer_mass_per_area Method
layer_mass_per_area(field, mesh)Convert per-cell layer mass [kg cell⁻¹] to mass per horizontal area [kg m⁻²] without changing topology-native storage.
AtmosTransport.Output.missing_height_rule Method
missing_height_rule(source) -> AbstractMissingHeightRuleHow records of source without any vertical coordinate are placed: LowestLayerWithoutHeight for OCO2LiteSource and TableSource, UnplacedWithoutHeight for ObsPackSource.
AtmosTransport.Output.model_surface_height Method
model_surface_height(surface, cell::CellLocation) -> Float64Model surface height (m above sea level) of the cell containing an observation; NaN for NoModelSurfaceHeight.
AtmosTransport.Output.needs_column_humidity Method
needs_column_humidity(basis, mass_basis) -> BoolWhether a column's layer heights and interface pressures on the AbstractPressureBasis basis need its specific humidity: on a dry-basis run TotalFromHumidity builds the total pressures and the virtual temperature from it, for every placement (the heights of sample_column_layer!) and for averaging-kernel columns. DryInterfaces, and a moist-basis run, need none.
AtmosTransport.Output.observation_needs_humidity Method
observation_needs_humidity(sampler) -> BoolWhether observe_window_boundary! needs the specific humidity: the sampler builds its columns' heights and pressures on total pressures (TotalFromHumidity) on a dry-basis run.
AtmosTransport.Output.observation_output_spec Method
observation_output_spec(output_cfg; partition = nothing)Parse [output.observations] from the [output] table. Returns NoObservationOutput() when the subtable is absent or enabled = false, otherwise an ObservationOutputSpec. Unknown keys, a missing path or sources, and invalid choices raise ArgumentError. The file partition (one file vs. one per daily binary) follows [output].split unless partition is given; split is only read when observations are enabled.
AtmosTransport.Output.observe_window_boundary! Method
observe_window_boundary!(sampler, state, time_seconds; next_window_seconds, temperature = nothing,
humidity = nothing)Sample state at a met-window end time_seconds after the run origin. next_window_seconds is the length of the window that starts now (it sets which soundings receive their first sample). temperature, when given, is a per-layer temperature field (K, k = 1 at the top) used for site layer heights, either with the air-mass layout or, on the cubed sphere, as interior-only panels; otherwise the configured constant applies. humidity is the specific humidity (kg kg⁻¹ of moist air, k = 1 at the top) at this window end, in the same layouts; a sampler that builds its columns on total pressures on a dry-basis run (TotalFromHumidity: the layer heights of every row, pressure placement, averaging-kernel columns) requires it and otherwise ignores it. Call once at t = 0 on the initial state and after every window.
AtmosTransport.Output.placement_layer Method
placement_layer(placement, z_half, p_half) -> IntModel layer (k = 1 top) of a VerticalPlacement in one sampled column: by height above the model surface (intake_layer_index on the hypsometric interface heights z_half), by pressure (pressure_layer_index on the interface pressures p_half), or the lowest layer.
AtmosTransport.Output.point_elevation Method
point_elevation(dem, lon, lat) -> Float64Ground elevation (m above sea level) of dem at the point, NaN where the DEM has no value (outside its coverage, fill, or NoPointElevation).
AtmosTransport.Output.read_observation_requests Method
read_observation_requests(source, source_index, origin, dates) -> (soundings, sites)Expand the source's path template for the run days and read every file into SoundingRequests and SiteRequests (one of the two is empty, depending on the source mode). Times are Float64 seconds since origin. Rows with fill values or impossible coordinates are skipped; a source that resolves to no file at all logs a warning.
AtmosTransport.Output.read_oco2_retrieval_columns Method
read_oco2_retrieval_columns(ds, rows; label = "OCO-2 file") -> Vector{RetrievalColumn{HatLevelProjection}}The retrieval of records rows (1-based indices along sounding_id) of an open OCO-2 or OCO-3 Lite file or OCO-2 v11 MIP 10-second file, as level columns (RetrievalColumn with HatLevelProjection): the profile values of these retrievals sit on 20 levels with the profile linear in pressure between them. Read per record:
the level pressures:
pressure_levels (levels, sounding)(Lite files) orsigma_levels (levels)timespsurf (sounding)(MIP files), converted to Pa with theirunits(hPa);pressure_weight,xco2_averaging_kernel(normalized, used as it is, not multiplied by the weights) andco2_profile_apriori(converted to mol/mol with itsunits, ppm);xco2_apriori, the prior column, when the file has it (converted to mol/mol): the column is then. For the 10-s averages it differs from (the weights and the prior were averaged separately) by up to about 0.01 ppm.
The files store the levels from space to the surface; each record is turned surface first (by its pressures, so either order is read correctly). The surface pressure is the bottom level. Every field must be finite and pass the RetrievalColumn checks (weights summing to 1); an invalid record is an error naming its sounding_id.
AtmosTransport.Output.resolve_placement Method
resolve_placement(spec::VerticalPlacementSpec, missing_height, request, cell, terrain)
-> Union{VerticalPlacement, Nothing}Place a SoundingRequest or SiteRequest in the column of its containing cell by the first of spec.coordinates (AbstractVerticalCoordinate, in preference order) that places it:
HeightAboveGroundCoordinate: the record's height above ground( intake_height, oraltitude − elevationwith the record's or station's elevation;record_height), else= altitudeminus the DEM ground elevation at the point (altitude_minus_dem). The record is placedabove the model surface. PressureCoordinate: the record'spressure(pressure), when it isvalid_pressure(finite and positive).
A record that none of the coordinates place is unplaced (nothing) when it states any vertical coordinate (an intake_height, an altitude, a valid pressure), e.g. an altitude without a ground elevation (no record elevation, no DEM value), or a coordinate the run does not use. One without any vertical coordinate goes to the lowest layer (lowest_layer) under LowestLayerWithoutHeight and is unplaced under UnplacedWithoutHeight (missing_height, from missing_height_rule of the record's source). The model surface height is never used as the true ground.
spec.altitude_placement = AbsoluteAltitudeAbove(h₀) then re-places records placed by a height pressure is one of the coordinates), else by absolute altitude: the stated altitude, else the ground elevation (the record's, else the DEM value at the point) plus intake_height; a record with neither keeps its height above the ground.
AtmosTransport.Output.retrieval_column_value Method
retrieval_column_value(p_half, air, column::RetrievalColumn, x) -> Float64
retrieval_column_value(p_half, column::RetrievalColumn{LayerRebin}, x) -> Float64The simulated column x (dry mole fraction, top first) on the model interface pressures p_half (Pa, top first, total pressures) and air masses air (read by the hat projection only): retrieval_column_weights! and retrieval_prior_offset in one call.
AtmosTransport.Output.retrieval_column_weights! Method
retrieval_column_weights!(H, s, p_half, air, column::RetrievalColumn) -> H
retrieval_column_weights!(H, s, p_half, column::RetrievalColumn{LayerRebin}) -> H
retrieval_column_weights!(H, s, p_half, r, h, a) -> HWeights of the averaging-kernel column on the model layers: with the model profile k = 1 at the top),
(retrieval_prior_offset) with the column's prior column prior_column) when it gives one, stretch_model_interfaces!), onto the retrieval's values as its mapping says: the rebin LayerRebin (retrieval_rebin_matrix; the column of TM5-4DVar's OCO-2 operator, averaging_kernels.F90, lines 228-235 and 245), or the hat projection of HatLevelProjection, which weights each model layer by its air mass air (kg per cell, top first; the run's dry air mass on a dry basis). Every row of retrieval_projection_matrix). p_half are the model interface pressures (Pa, top first; total pressures, so that they compare with the retrieval's), s a scratch vector of the same length that receives the stretched interfaces. A layer column ignores air; the form without it takes layer columns only. The last form takes the retrieval interfaces r (surface first), pressure weights h and kernel a of a layer column as they are, without the checks of RetrievalColumn (weights that do not sum to 1, as TM5's
AtmosTransport.Output.retrieval_layer_count Method
retrieval_layer_count(column::RetrievalColumn) -> IntNumber of retrieval values of a RetrievalColumn: its layers (LayerRebin) or levels (HatLevelProjection).
AtmosTransport.Output.retrieval_model_error_variance Method
retrieval_model_error_variance(column::RetrievalColumn) -> Float64The model-error variance of the averaging-kernel column from the uncertainty profile_sigma), the layers taken independent: profile_sigma. It depends on the record only, so it is fixed for an inversion and the cost stays quadratic.
This is analogous to, not the same as, TM5-4DVar's model error: its CH4 TROPOMI routine (averaging_kernels.F90, line 669, and Satellite.py of the CH4 project) evaluates profile_sigma is not the retrieval's a-priori uncertainty, whose effect (the smoothing error) the averaging kernel already represents.
AtmosTransport.Output.retrieval_prior_offset Method
retrieval_prior_offset(column::RetrievalColumn) -> Float64
retrieval_prior_offset(h, a, prior) -> Float64The prior term of the averaging-kernel column, which does not depend on the model: prior_column dot_product(pres_weights - W, prior_profile); the raw form always).
AtmosTransport.Output.retrieval_profile! Method
retrieval_profile!(xr, s, p_half, air, column::RetrievalColumn, x) -> xr
retrieval_profile!(xr, s, p_half, column::RetrievalColumn{LayerRebin}, x) -> xrThe model profile x (top first) on the retrieval layers or levels (surface first), air as in retrieval_column_weights!). s is scratch for the stretched interfaces. A diagnostic: the column itself is
AtmosTransport.Output.retrieval_projection_matrix Method
retrieval_projection_matrix(p_half, air, column::RetrievalColumn) -> Matrix{Float64}The projection matrix N × Nz, retrieval values surface first, model layers top first) of the column's mapping on the model column (interface pressures p_half, Pa, top first; air masses air, kg per cell, read by the hat projection only) stretched onto the retrieval column: the rebin LayerRebin, the dry-air L2 projection onto the levels' hats for HatLevelProjection.
AtmosTransport.Output.retrieval_rebin_matrix Method
retrieval_rebin_matrix(p_half, column::RetrievalColumn{LayerRebin}) -> Matrix{Float64}
retrieval_rebin_matrix(p_half, r) -> Matrix{Float64}The redistribution matrix N × Nz, retrieval layers surface first, model layers top first) of TM5-4DVar's inv_rebin (averaging_kernels.F90, lines 60-146) on the model column stretched onto the retrieval column: LayerRebin.
AtmosTransport.Output.runtime_output_spec Method
runtime_output_spec(output_cfg, FT; default_path="", default_cap_hours=8760, fallback_hours=[])Parse the run-time output contract from TOML-compatible [output] settings.
Preferred keys are path, cadence_hours or hours, and split = "single" | "daily". Legacy snapshot_file, snapshot_hours, and snapshot_interval_hours remain accepted.
AtmosTransport.Output.sample_column_layer! Method
sample_column_layer!(column::PlacementColumn, p_half, z_half, placement, air_column, area, g, p_top,
temperature, basis, mass_basis) -> IntThe layer (k = 1 top) of a VerticalPlacement in one sampled column, from the column alone: the interface pressures of the air mass (interface_pressures! into p_half, p_top; dry pressures on a dry-basis run), the hypsometric interface heights above the model surface on the vertical basis of basis (placement_heights! into z_half, with the AbstractLayerTemperature temperature: total pressures and virtual temperature for TotalFromHumidity on a dry basis), then column_layer!. column.humidity must hold the column's specific humidity whenever the basis needs it (needs_column_humidity), for every placement, since the heights use it. The forward observation sampler and the inversion's placed point observations both choose their layers with this function.
AtmosTransport.Output.samples_observations Method
Whether the runner must visit every met-window end for this sampler.
sourceAtmosTransport.Output.stretch_model_interfaces! Method
stretch_model_interfaces!(s, p_half, surface_pa, top_pa) -> sTM5-4DVar's stretch of the model column onto a retrieval column (averaging_kernels.F90, lines 213-219): the model interface pressures p_half (Pa, top first, p_half[end] the model surface pressure p_half[1] the model top surface_pa) and the model top on the retrieval top top_pa),
Each model layer keeps its share
AtmosTransport.Output.tm5_layer_column Method
tm5_layer_column(column::RetrievalColumn{HatLevelProjection}) -> RetrievalColumn{LayerRebin}TM5-4DVar's layer form of a level retrieval (OCO-2/OCO-3 10-s files in proj/tracer/CO2/py/Observations.py, lines 7016-7052, used by Satellite.py, lines 707-717): the N levels become the interfaces of N − 1 layers, the averaging kernel and the prior are interpolated linearly in pressure to the layer midpoints (the mean of the two levels), and the pressure weights are the layer thicknesses profile_sigma is averaged like the kernel. The prior column is TM5's, prior_column of the record is not carried). For comparisons with TM5-4DVAR; the hat projection (HatLevelProjection) is the consistent mapping of level retrievals.
AtmosTransport.Output.with_netcdf_lock Method
with_netcdf_lock(f)Run f() holding the process-wide NetCDF lock. Every runtime NetCDF write (snapshot files, the snapshot stream, observation streams) goes through it, because netcdf-c is not thread-safe and daily snapshot files are written on a background task.
AtmosTransport.Output.write_snapshot_binary Method
write_snapshot_binary(path, frames, grid; mass_basis=:dry, options=SnapshotWriteOptions(),
physics_attributes=Dict())Write CS snapshots to a self-describing binary file. Skips NetCDF library overhead entirely; pair with scripts/postprocess/binary_to_netcdf.jl for the offline conversion. Throws if grid.horizontal is not a CubedSphereMesh.
AtmosTransport.Output.write_snapshot_netcdf Method
write_snapshot_netcdf(path, frames, grid; mass_basis=:dry, options=SnapshotWriteOptions(),
fields=output_field_spec(), physics_attributes=Dict())Write topology-aware runtime snapshots to NetCDF.
The output contains full per-level VMR fields, stored air mass, layer mass-per-area diagnostics, column air mass per area, and tracer column means. Reduced-Gaussian files also carry a legacy lon/lat raster view for quick plots. Cubed-sphere files carry panel lon/lat coordinates and a cubed_sphere grid-mapping variable modeled after GEOS-Chem diagnostics.
Visualization
Field selection uses typed values. Pass ColumnMean(), ColumnSum(), LevelSlice(), or SurfaceSlice() as the transform keyword to fieldview; LevelSlice() also requires level. Pass NativeUnit() or PPMUnit() as unit, and pass AllFrames() to frame_indices to select every frame. These selectors are exported by AtmosTransport.Visualization, not by the top-level module. For example:
using AtmosTransport.Visualization
snapshot = open_snapshot("output.nc")
surface = fieldview(snapshot, :co2; transform=SurfaceSlice(), time=1,
unit=PPMUnit())
levels = fieldview(snapshot, :co2; transform=LevelSlice(), level=10, time=1)AtmosTransport.Visualization Module
VisualizationTopology-aware snapshot visualization support.
This module owns the lightweight data layer only: snapshot discovery, field views, unit scaling, and topology-aware rasterization for quick maps. Makie plotting lives in AtmosTransportMakieExt so the model/runtime does not pay a plotting load cost unless a Makie backend is explicitly loaded.
AtmosTransport.Visualization.CubedSphereSnapshotTopology Type
CubedSphereSnapshotTopology(Nc, nlevel, panel_convention[, definition])Cubed-sphere snapshot geometry. Values are stored as (Xdim, Ydim, nf) for a single horizontal field, with nf == 6. definition is the mesh the snapshot was written on (coordinate and center laws, panel convention, longitude offset); it defaults to the panel convention's standard definition.
AtmosTransport.Visualization.HorizontalField Type
HorizontalFieldA topology-native horizontal field view from one snapshot time.
For LL/RG snapshots values is a (lon, lat) matrix. For CS snapshots it is a (Xdim, Ydim, nf) array until rasterized or plotted natively.
AtmosTransport.Visualization.LatLonSnapshotTopology Type
LatLonSnapshotTopology(lons, lats; grid_type=:latlon)Regular lon-lat snapshot geometry. Values are stored as (lon, lat).
AtmosTransport.Visualization.PlotSpec Type
PlotSpec(variable; transform=ColumnMean(), level=nothing, title=nothing, unit=NativeUnit())One panel specification for multi-panel plots and movies.
sourceAtmosTransport.Visualization.RasterField Type
RasterFieldRegular lon-lat representation used by fast debug maps and movies.
sourceAtmosTransport.Visualization.ReducedGaussianSnapshotTopology Type
ReducedGaussianSnapshotTopology(lons, lats, nrings, regridding)Reduced-Gaussian snapshot geometry after the current writer's ring-aware nearest-neighbor projection onto a regular lon-lat diagnostic grid.
sourceAtmosTransport.Visualization.SnapshotDataset Type
SnapshotDatasetMetadata for an AtmosTransport NetCDF snapshot file.
The object intentionally does not hold an open NetCDF handle. Field reads open the file briefly and close it immediately, which is robust for scripts, animations, and long debugging sessions.
sourceAtmosTransport.Visualization.SnapshotRegridCache Type
SnapshotRegridCache()Cache expensive topology-to-raster geometry, especially CS→LL conservative regridders, across frames in snapshot grids and movies.
sourceAtmosTransport.Visualization.as_raster Method
as_raster(field; resolution=(360, 181), cache=SnapshotRegridCache())Return a regular lon-lat RasterField for fast plotting.
LL and current RG diagnostic snapshots are already raster-like. CS fields are conservatively regridded to lon-lat and reuse cache across frames.
AtmosTransport.Visualization.catrine_map_curtains Method
catrine_map_curtains(at_path, gc_dir; kwargs...) -> NamedTupleCreate the CATRINE AtmosTransport/GEOS-Chem column-map and pressure-curtain comparison product. Output is controlled by the out_dir keyword. This specialized visualization requires a Makie backend.
AtmosTransport.Visualization.catrine_map_curtains_3way Method
catrine_map_curtains_3way(at_geos_path, at_era5_path, gc_dir; kwargs...) -> NamedTupleCompare GEOS-Chem with AtmosTransport runs driven by GEOS-IT and ERA5 in one CATRINE column-map and pressure-curtain product. Output is controlled by the out_dir keyword. This specialized visualization requires a Makie backend.
AtmosTransport.Visualization.fieldview Method
fieldview(snapshot, variable; transform=ColumnMean(), time=1, level=nothing, unit=NativeUnit())Load one topology-native horizontal field from a snapshot file.
time may be a one-based frame index or a snapshot hour. For CS snapshots, transform may be ColumnMean(), ColumnSum(), LevelSlice(), or SurfaceSlice(). Stored CS column means support column-only output; level selection uses original model indices and rejects levels that were not written. LL/RG snapshots currently support ColumnMean() only.
AtmosTransport.Visualization.mapplot! Method
mapplot!(axis, field; kwargs...)Render a topology-aware field into an existing Makie axis and return the plot object. A Makie backend must be loaded.
sourceAtmosTransport.Visualization.mapplot Method
mapplot(field; kwargs...) -> FigureRender one topology-aware HorizontalField as a lon-lat map. Load a Makie backend such as CairoMakie before calling this function. Cubed-sphere fields are conservatively rasterized and may reuse a SnapshotRegridCache.
AtmosTransport.Visualization.movie Method
movie(snapshot, variable, output_path; kwargs...) -> StringRender one snapshot variable to an animation and return output_path. A Makie backend must be loaded.
AtmosTransport.Visualization.movie_grid Method
movie_grid(snapshot, specs, output_path; kwargs...) -> StringRender several PlotSpec panels to one animation and return output_path. A Makie backend must be loaded.
AtmosTransport.Visualization.open_snapshot Method
open_snapshot(path) -> SnapshotDatasetRead snapshot metadata and infer its topology.
Supported formats are the current AtmosTransport LL/RG column-mean snapshots and CS panel snapshots written by run_driven_simulation.
AtmosTransport.Visualization.robust_colorrange Method
robust_colorrange(fields; trim=(0.01, 0.99))Compute a robust color range from one or more fields by ignoring non-finite values and clipping to quantiles.
sourceAtmosTransport.Visualization.snapshot_grid Method
snapshot_grid(snapshot, variable; kwargs...) -> FigureRender one snapshot variable at several output times in a shared figure. A Makie backend must be loaded.
source