Time windows#
Analysis times run from first_analysis through end inclusive, spaced by
assimilation_frequency. Give exactly one of start or first_analysis;
the other is derived, and both are populated on the config afterwards.
Field |
Meaning |
Use it when |
|---|---|---|
|
Start of the model run, not an analysis time. |
Observations exist independently of the model ( |
|
The first analysis time itself. |
The analysis times must land on times fixed by something else — in particular |
start exists because in CESM+DART cycling the model advances one
assimilation period before the first assimilation. That implicit + freq is
easy to trip over, so state it directly with first_analysis whenever you
know the analysis times you want:
# These two are identical
ObsGenConfig(start=datetime.datetime(2010, 5, 1), ...) # first analysis 06Z
ObsGenConfig(first_analysis=datetime.datetime(2010, 5, 1, 6), ...) # same thing, said directly
Passing neither, passing both, or configuring a run with no analysis times at
all (first_analysis > end) raises ValueError at construction.
All ObsGenConfig fields are keyword-only.
Window bounds#
Each analysis time T gets the window (T - freq/2, T + freq/2] — open
below, closed above. This matches DART’s documented convention (see
assimilation_code/programs/obs_sequence_tool/obs_sequence_tool.rst):
“the windows should be centered around the assimilation time starting at
minus 1/2 the window time plus 1 second, and ending at exactly plus 1/2 the
window time.”
Windows are contiguous and non-overlapping. Adjacent windows share a boundary
instant, and the closed upper bound assigns it to the earlier window, so no
observation is ever written to two files. Note that observations before
first_analysis - freq/2 are deliberately unused — they belong to an earlier
analysis, which happened before this run began.
Assimilation frequency#
assimilation_frequency accepts any datetime.timedelta that is an even
whole number of seconds (so that the half-width freq/2 lands on an integer
second, since DART times are integer day/second pairs). Sub-hourly windows are
supported:
import datetime
from dartobsgen import ObsGenConfig
# 6-hour windows (default): analyses at 06Z, 12Z, 18Z, 00Z
config = ObsGenConfig(..., assimilation_frequency=datetime.timedelta(hours=6))
# 30-minute windows
config = ObsGenConfig(..., assimilation_frequency=datetime.timedelta(minutes=30))
To land on conventional analysis times, either name the first one directly
with first_analysis=datetime.datetime(2010, 5, 1, 6) (06Z), or set start
one frequency before it: start=datetime.datetime(2010, 5, 1) (00Z).