dartobsgen.PerfectModelSource#

class dartobsgen.PerfectModelSource(pmo_run_dir, obs_network, perfect_model_obs_exe='./perfect_model_obs', state_provider=None)[source]#

Bases: DataSource

Data source that generates synthetic observations via DART’s perfect_model_obs.

For each assimilation window, this source:

  1. Filters the observing network to the requested obs types and bounding box.

  2. Writes a template obs_seq.in (placeholder observation values 0.0).

  3. Patches input.nml with the obs_seq filenames and window time bounds.

  4. Runs perfect_model_obs in an isolated per-window directory.

  5. Moves the resulting obs_seq.out to the caller-specified output path.

Parameters:
  • pmo_run_dir (str) – Directory containing the compiled perfect_model_obs executable, a base input.nml, and every input file that input.nml references. Each window runs in a temporary subdirectory of {pmo_run_dir}/windows/ that symlinks back to the shared files. Checked at construction (see _check_run_dir()), so a run directory missing the executable or a file named in input.nml fails here rather than inside perfect_model_obs.

  • obs_network (list[ObsNetworkEntry]) – The synthetic observing network. Each entry defines one observation location, type, error variance, and time offset within the window.

  • perfect_model_obs_exe (str) – Name or path of the executable relative to the window directory. Default is "./perfect_model_obs".

  • state_provider (ModelStateProvider, optional) –

    Maps each window to a single-timeslice model state file (e.g. MOM6StateProvider slicing the output of a model run). When given, each window’s input.nml points input_state_files at that window’s state, and observations are placed at the state’s valid time (plus each entry’s time_offset). Windows with no available state are skipped.

    Because observations land on the state’s valid time, the run’s analysis times must line up with the model output times. Configure that with ObsGenConfig(first_analysis=<first model output time>) rather than start, and see check_coverage(), which reports the alignment before any window runs.

Notes

Parallel safety: each call to write_obs_seq() runs in its own subdirectory, so multiple ProcessPoolExecutor workers can run simultaneously without file conflicts.

Model state: perfect_model_obs interpolates from the model state file named in input.nml. Without a state_provider, this class assumes a single fixed initial-conditions file valid for the entire run (appropriate for Lorenz-type models or a frozen-truth scenario). With a state_provider, each window gets the model state valid at that window’s time. perfect_model_obs cannot advance large models, so observation times must sit at the state’s valid time — hence the obs reference time switches from analysis time to state valid time.

__init__(pmo_run_dir, obs_network, perfect_model_obs_exe='./perfect_model_obs', state_provider=None)[source]#
Parameters:

Methods

__init__(pmo_run_dir, obs_network[, ...])

check_coverage(windows)

Report how the run's windows line up with the available model states.

write_obs_seq(output_file, analysis_time, ...)

Generate synthetic obs for one window via perfect_model_obs.

check_coverage(windows)[source]#

Report how the run’s windows line up with the available model states.

Synthetic observations can only be produced where a model state exists, so a run whose analysis times miss the model output times writes nothing at all. This runs before any window and classifies every state as used (the earliest in its window), shadowed (in a window that already has an earlier state, so ignored) or outside (in no window). It prints a one-block summary, and raises when no state is usable — the case that would otherwise look like a silent success.

Does nothing without a state_provider, or when the provider cannot enumerate its states (available_times() returns None).

Raises:

ValueError – If no model state falls in any window. The message names the first_analysis that would capture the model output.

Parameters:

windows (list[tuple[datetime, datetime, datetime]])

Return type:

None

write_obs_seq(output_file, analysis_time, date0, date1, lat_min, lat_max, lon_min, lon_max, obs_types, obs_type_map)[source]#

Generate synthetic obs for one window via perfect_model_obs.

Network entries are placed at analysis_time + entry.time_offset and the window (date0, date1] bounds the namelist’s obs times.

Returns:

True if perfect_model_obs ran successfully and output_file was written; False otherwise (including windows with no observations or no model state).

Return type:

bool

Parameters: