Coverage for src/gwtransport/_time.py: 100%

9 statements  

« prev     ^ index     » next       coverage.py v7.15.3, created at 2026-08-04 21:13 +0000

1""" 

2Time-axis conversion atoms for transport-module entry points. 

3 

4The transport modules across :mod:`gwtransport` -- advection, diffusion, 

5deposition, percolation, recharge, residence time, radial ASR and front 

6tracking -- repeatedly convert a :class:`pandas.DatetimeIndex` of bin edges into 

7a float64 array of days relative to a reference timestamp. The two helpers here 

8factor that idiom once so the conversion (and its object-dtype-on-old-pandas 

9contract) lives in a single place. 

10 

11Both helpers return ``float64`` arrays. ``tedges_to_days`` measures each edge 

12relative to ``ref`` (defaulting to the first edge); ``dt_to_days`` returns the 

13successive bin widths in days. The ``ref`` keyword is load-bearing: cross-array 

14conversions (e.g. output edges measured against the input-flow reference) must 

15share a common origin. 

16 

17This module has no public API; importers are the transport modules themselves 

18plus their unit tests. 

19""" 

20 

21from __future__ import annotations 

22 

23import numpy as np 

24import numpy.typing as npt 

25import pandas as pd 

26 

27 

28def tedges_to_days(tedges: pd.DatetimeIndex, *, ref: pd.Timestamp | None = None) -> npt.NDArray[np.floating]: 

29 """Convert time-bin edges to days relative to a reference timestamp. 

30 

31 Parameters 

32 ---------- 

33 tedges : DatetimeIndex 

34 Time-bin edges to convert. 

35 ref : Timestamp or None, optional 

36 Reference timestamp mapped to day zero. Defaults to ``tedges[0]`` when 

37 ``None``. Pass a shared reference when converting a second edge array 

38 that must align to the same origin. 

39 

40 Returns 

41 ------- 

42 ndarray 

43 Float64 array of days since ``ref``, one value per edge. 

44 """ 

45 origin = tedges[0] if ref is None else ref 

46 return ((tedges - origin) / pd.Timedelta(days=1)).to_numpy(dtype=float) 

47 

48 

49def dt_to_days(t: pd.DatetimeIndex) -> npt.NDArray[np.floating]: 

50 """Convert successive time-bin widths to days. 

51 

52 Parameters 

53 ---------- 

54 t : DatetimeIndex 

55 Time-bin edges (n+1 edges for n bins). 

56 

57 Returns 

58 ------- 

59 ndarray 

60 Float64 array of bin widths in days (length ``len(t) - 1``). 

61 """ 

62 return (np.diff(t) / pd.Timedelta(days=1)).astype(float)