slv.measurements.mobile.receptors#

STILT receptors for the TRAX record: one multipoint receptor per 2-km segment crossing.

The paper-2 inversion samples TRAX CH4 at the staged 2-km network points (load_trax_points()). Each staged point owns a segment: the 50-m network points nearest to it. Both point sets are generated the same way, lair.geo.points_along_line on the UTA line network (load_trax_points()), so shared track is one row of points (load_trax_network_points()); a crossing on one line releases only from that line’s points of the segment (release_points()). Every time the train crosses a segment (find_segment_crossings()) it gets one PYSTILT MultiPointReceptor that releases particles from all of the segment’s 50-m points at the median crossing time (build_trax_receptors()). PYSTILT spreads numpar evenly over the release points and writes their mean footprint, so the 50-m footprints come out already aggregated to the 2-km point. The CH4 value that pairs with a receptor is the mean over the same 50-m points during the crossing (i.e. the transect-matrix row averaged over the segment).

Segment membership is fixed by geometry alone: it does not depend on the inlet lag or on which periods pass calibration QC, so receptors can be built (and run) before those decisions are final; QC later selects which crossings enter the inversion. Crossings are found from the GPS positions of the on-track rows of obs.parquet, so periods with no LGR data get no receptors.

Dwells. Half the record is not a traverse at all: the train sits outdoors at a line terminus between runs or parked on a yard track, which is 39 % of the CH4 rows at the yards plus 31 % of the crossing time at the termini. Sitting still at a known outdoor position is a stationary measurement, so find_dwells() picks those periods out (the train stays within radius for at least min_duration) and build_dwell_receptors() turns each hour of one into a single PointReceptor at the dwell’s median position. Indoor shed air is excluded upstream by loading fixes with location="outdoor".

Both builders release when the air was sampled – a crossing at its median fix time, a dwell hour at the median fix time inside that hour – rather than on the hour, and both accept an hours window (local time) so a project can start with the afternoon and add the rest later without rebuilding what it already has.

Attributes

LINE_LETTERS

Letters of the TRAX lines as load_trax_points() tags them (bit i of a line mask).

RECEPTOR_COLUMNS

Column order of a PYSTILT receptor CSV (r_idx groups rows into one receptor).

Functions

build_dwell_receptors

PYSTILT receptor table (RECEPTOR_COLUMNS) for the dwell periods.

build_trax_receptors

PYSTILT receptor table (RECEPTOR_COLUMNS) from a crossings table.

filter_receptor_hours

Keep rows whose time falls in those local-time hours (None keeps all).

find_dwells

Periods where the train stayed put: parked on a yard track or waiting at a terminus.

find_segment_crossings

Split the GPS record into crossings of the 2-km segments.

label_dwell_site

Where each dwell is: yard_name (JRRSC / MRSC, from the packaged storage polygons) and segment (nearest 2-km segment, NaN beyond max_dist).

load_trax_fixes

Time_UTC, Latitude_deg, Longitude_deg of the location rows of the cached TRAX record (obs.parquet), one row per distinct second, time-sorted.

load_trax_network_points

The 50-m network points with their 2-km segment membership.

release_points

Index of the segment's points on every line in lines (all of them if lines is empty).