tracmass.ParticleRecorder#

class tracmass.ParticleRecorder(filepath, metadata=None)[source]#

Bases: object

Streams trajectory snapshots and deactivation events to a Parquet file.

Each call to record() appends active-particle positions as a new row group with event_type="snapshot" (at a window boundary); each call to record_rampup() the same with event_type="rampup" (extra saves inside the first windows of a run). Each call to record_deactivations() appends newly-stopped particles with event_type="deactivated". Call close() (or use the recorder as a context manager) to finalise the file.

The unified schema contains 13 columns: event_type, window, dtm, id, x, y, z, ia, ja, ka, tt, t0, reason. Filter on event_type when analysing a single event class.

x / ia and y / ja are written in full-grid (absolute) indices: grid_offset — set from grid.i_offset / grid.j_offset by the integrators — is added to the in-memory, subset-relative positions. A non-zero offset is also stored in the run metadata as i_offset / j_offset.

Run metadata (GCM adapter name, integration strategy, etc.) is stored as a JSON object under the Parquet schema metadata key "tracmass.run". Read it back without loading row data:

import json, pyarrow.parquet as pq
meta = json.loads(pq.read_schema("traj.parquet").metadata[b"tracmass.run"])
Parameters:
  • filepath (str) – Output .parquet file path. The file is created on the first write.

  • metadata (dict, optional) –

    Arbitrary JSON-serialisable key/value pairs stored in the Parquet schema metadata under the key "tracmass.run". Typical fields:

    • "gcm" — GCM adapter name, e.g. "glorys" or "theoretical"

    • "integration" — function used, e.g. "time_dependent"

    • "n_windows" — number of GCM windows

    • "no_wflux" — whether vertical fluxes were disabled

grid_offset#

(i_offset, j_offset) added to x/ia and y/ja on write. Default (0, 0).

Type:

tuple[int, int]

metadata#

Run metadata written with the file (a copy of metadata); may be extended until the first write.

Type:

dict

Examples

>>> meta = dict(gcm="glorys", integration="time_dependent",
...             n_windows=50, no_wflux=True)
>>> with ParticleRecorder("traj.parquet", metadata=meta) as rec:
...     result = tracmass.time_dependent(
...         state, grid, lazy, fluxes_fn, n_windows=50, recorder=rec,
...         no_wflux=True,
...     )
__init__(filepath, metadata=None)[source]#
Parameters:
  • filepath (str)

  • metadata (dict | None)

Methods

__init__(filepath[, metadata])

close()

Finalise and close the Parquet file.

record(state[, dtm, window])

Append active-particle positions as a new row group.

record_deactivations(state, mask[, dtm, window])

Append deactivated particles identified by mask.

record_rampup(state[, dtm, window])

Append active-particle positions saved inside a window.

record(state, dtm=None, *, window=0)[source]#

Append active-particle positions as a new row group.

Parameters:
  • state (ParticleState) – Current particle state; only active particles are written.

  • dtm (pd.Timestamp or datetime-like, optional) – Timestamp stored in the dtm column. None → NaT.

  • window (int, optional) – Window index (0-based). Default 0.

Return type:

None

record_rampup(state, dtm=None, *, window=0)[source]#

Append active-particle positions saved inside a window.

Like record(), but with event_type="rampup": the extra saves of the ramp-up period (see rampup_windows in tracmass.time_dependent()). The run metadata’s save_dt_seconds gives the time between consecutive saves.

Parameters:
  • state (ParticleState) – Current particle state; only active particles are written.

  • dtm (pd.Timestamp or datetime-like, optional) – Time of the save (inside the window).

  • window (int, optional) – Index of the window the save falls in.

Return type:

None

record_deactivations(state, mask, dtm=None, *, window=0)[source]#

Append deactivated particles identified by mask.

Parameters:
  • state (ParticleState) – Particle state after the integration window.

  • mask (array-like of bool, shape (N,)) – Boolean mask selecting the newly-deactivated particles. Typically active_before & (reason != 0).

  • dtm (pd.Timestamp or datetime-like, optional) – Timestamp stored in the dtm column. None → NaT.

  • window (int, optional) – Window index (0-based). Default 0.

Return type:

None

close()[source]#

Finalise and close the Parquet file.

Safe to call even if no events were recorded.

Return type:

None