Time Primitives#
Classes that represent time anchors and time windows used throughout variable extraction. TimeAnchor wraps a column name and an optional offset; TimeWindow pairs a tmin and tmax anchor into a single object passed through the extraction pipeline.
- class corr_vars.utils.time.TimeAnchor(bound)[source]#
Bases:
object- Parameters:
bound (
str|tuple[str,str] |datetime|date|Expr)
- column: str | None#
- delta: tuple[str, ...] | None#
- expr: Expr#
- property is_relative: bool#
Whether a delta was applied — independently of what it was applied to.
- property is_literal: bool#
Whether this anchor is a fixed timestamp rather than a column.
- copy()[source]#
Return a copy of this anchor.
The copy shares only immutable state — column, delta and the polars expression — so re-pointing one of them leaves the original alone.
- Return type:
- shifted_by(delta)[source]#
Return a copy of this anchor moved by delta.
Deltas stack: shifting
("icu_admission", "+2h")by"-1h"keeps the column, applies both offsets and appends todelta. A fixed timestamp is moved to the offset timestamp.Either way the result reports
is_relative, and a shifted literal staysis_literal: the two describe different things — what the anchor is fixed to, and whether it was moved.- Parameters:
delta (
str|timedelta) – Offset such as"24h"or"-30m".- Returns:
The shifted anchor.
- Return type:
- Raises:
ValueError – If delta is not a valid offset, or if shifting a fixed timestamp leaves the representable datetime range — which is what moving
UNBOUNDED_TMINfurther back orUNBOUNDED_TMAXfurther forward does.
- class corr_vars.utils.time.TimeWindow(tmin=None, tmax=None)[source]#
Bases:
object- Parameters:
tmin (
TimeAnchor|str|tuple[str,str] |datetime|date|None)tmax (
TimeAnchor|str|tuple[str,str] |datetime|date|None)
- tmin: TimeAnchor#
- tmax: TimeAnchor#
- classmethod from_obs_level(obs_level)[source]#
Build a
TimeWindowfrom an observation level’st_min/t_max.- Parameters:
obs_level (
ObsLevel)- Return type:
- classmethod from_anchor_and_duration(anchor, duration)[source]#
Build
[anchor, anchor + duration]from one anchor and a length.Spares callers from repeating the anchor on both bounds — instead of
TimeWindow("icu_admission", ("icu_admission", "+28d"))writeTimeWindow.from_anchor_and_duration("icu_admission", "28d"). This is the natural shape for a T0-plus-horizon follow-up window.- Parameters:
anchor (
TimeAnchor|str|tuple[str,str] |datetime|date) – The window start (T0). A column name,(column, delta)tuple, datetime/date literal, or an existingTimeAnchor.duration (
str|timedelta) – Horizon length as a polars-duration string ("28d") or atimedelta. A leading sign is optional (+).
- Return type:
- anchored_to_day(day_start=None)[source]#
Return a copy with both bounds snapped to a day boundary.
Snaps
tminandtmaxviatruncate_to_day()(day_start=Nonefor calendar days,"6h"for ICU days). The original window is unchanged, so only the caller that wants day-anchored bounds is affected. Whentmaxistmin + Ndboth bounds shift by the same intra-day amount, so the horizon length is preserved.- Parameters:
day_start (
str|timedelta|None)- Return type:
- time_difference(*, unit='s', total=True)[source]#
- Parameters:
unit (
Literal['s','m','h','d','w'])total (
bool)
- Return type:
Expr
- property tmin_expr: Expr#
- property filled_tmin_expr: Expr#
- property tmax_expr: Expr#
- property filled_tmax_expr: Expr#
- property tmid_expr: Expr#
- property duration_expr: Expr#
- property is_relative: bool#
- property is_literal: bool#
- property any_timebound_in_year_9999_expr: Expr#
- property any_timebound_null_expr: Expr#
- property tmin_after_tmax_expr: Expr#
- class corr_vars.utils.time.WindowRelation(value)[source]#
Bases:
Flag- CONTAINED = 1#
- OVERLAPS_LEFT = 2#
- OVERLAPS_RIGHT = 4#
- COVERS_WINDOW = 8#
- ANY_LEFT_OVERLAP = 11#
- ANY_RIGHT_OVERLAP = 13#
- ANY_OVERLAP = 15#
- class corr_vars.utils.time.WindowOverlap[source]#
Bases:
object- static contains_expr(record, window, closed='both')[source]#
- Parameters:
record (
TimeAnchor)window (
TimeWindow)closed (
Literal['left','right','both','none'])
- Return type:
Expr
- static relation_expr(record, window)[source]#
- Parameters:
record (
TimeWindow)window (
TimeWindow)
- Return type:
dict[WindowRelation,Expr]
- static overlap_expr(record, window, relation)[source]#
- Parameters:
record (
TimeWindow)window (
TimeWindow)relation (
WindowRelation)
- Return type:
Expr
- static classify_expr(record, window, *, default=None)[source]#
- Parameters:
record (
TimeWindow)window (
TimeWindow)default (
WindowRelation|None)
- Return type:
Expr
- corr_vars.utils.time.compatible_with_time_anchor(df, time_anchor)[source]#
- Parameters:
df (
DataFrame|LazyFrame)time_anchor (
TimeAnchor)
- Return type:
bool
- corr_vars.utils.time.compatible_with_time_window(df, time_window)[source]#
- Parameters:
df (
DataFrame|LazyFrame)time_window (
TimeWindow)
- Return type:
bool
- corr_vars.utils.time.resolve_time_anchor(value, parent)[source]#
Resolve a requirement’s
tmin/tmaxagainst the parent’s anchor.Four notations are accepted:
"inherit"— the parent’s anchor unchanged.("inherit", "-1h")— the parent’s anchor shifted by the delta. Invars.jsonthis is written as["inherit", "-1h"]."-1h"— shorthand for the previous form; any bare delta is read relative to the parent, since no column is named like one.anything else — an anchor of its own (column,
(column, delta)orNonefor unbounded), returned untouched.
- Parameters:
value (
Union[str,tuple[str,str],Literal['inherit'],None]) – The requirement’s configured anchor.parent (
TimeAnchor) – The anchor of the same side of the parent variable’s window.
- Return type:
TimeAnchor|str|tuple[str,str] |None- Returns:
The resolved anchor, ready to be passed to
TimeWindow.
- corr_vars.utils.time.truncate_to_day(expr, *, day_start=None)[source]#
Snap a datetime expression to the start of the day it falls in.
day_startshifts where a “day” begins, letting the same helper express different day conventions:None— calendar day: the boundary is midnight (00:00)."6h"— ICU day: the boundary is06:00, so timestamps between midnight and06:00roll into the previous day (05:59→06:00yesterday,06:00→06:00today). The offset-truncate-offset form handles this wrap without any hour-of-day branching.
The result keeps the
Datetimedtype (at the boundary time), so downstream datetime arithmetic is unaffected.day_startis a non-negative offset.- Parameters:
expr (
Expr)day_start (
str|timedelta|None)
- Return type:
Expr
- corr_vars.utils.time.format_delta(delta)[source]#
Render a chain of offsets with an explicit sign in front of each.
A positive offset is stored without a sign, so spelling every sign out is what keeps a chain readable:
("2h", "-1h", "3d")becomes"+ 2h - 1h + 3d".- Parameters:
delta (
str|Sequence[str]) – The offsets, or a single one.- Return type:
str- Returns:
The chain with an operator in front of every offset.