tracmass.ParticleRecorder#
- class tracmass.ParticleRecorder(filepath, metadata=None)[source]#
Bases:
objectStreams trajectory snapshots and deactivation events to a Parquet file.
Each call to
record()appends active-particle positions as a new row group withevent_type="snapshot"(at a window boundary); each call torecord_rampup()the same withevent_type="rampup"(extra saves inside the first windows of a run). Each call torecord_deactivations()appends newly-stopped particles withevent_type="deactivated". Callclose()(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 onevent_typewhen analysing a single event class.x/iaandy/jaare written in full-grid (absolute) indices:grid_offset— set fromgrid.i_offset/grid.j_offsetby the integrators — is added to the in-memory, subset-relative positions. A non-zero offset is also stored in the run metadata asi_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.parquetfile 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 tox/iaandy/jaon 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:
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, ... )
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.Timestampordatetime-like, optional) – Timestamp stored in thedtmcolumn.None→NaT.window (
int, optional) – Window index (0-based). Default0.
- Return type:
None
- record_rampup(state, dtm=None, *, window=0)[source]#
Append active-particle positions saved inside a window.
Like
record(), but withevent_type="rampup": the extra saves of the ramp-up period (seerampup_windowsintracmass.time_dependent()). The run metadata’ssave_dt_secondsgives the time between consecutive saves.- Parameters:
state (
ParticleState) – Current particle state; only active particles are written.dtm (
pd.Timestampordatetime-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-likeofbool,shape (N,)) – Boolean mask selecting the newly-deactivated particles. Typicallyactive_before & (reason != 0).dtm (
pd.Timestampordatetime-like, optional) – Timestamp stored in thedtmcolumn.None→NaT.window (
int, optional) – Window index (0-based). Default0.
- Return type:
None