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

9 statements  

« prev     ^ index     » next       coverage.py v7.15.0, created at 2026-07-07 21:17 +0000

1""" 

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

3 

4The transport modules in :mod:`gwtransport.advection`, 

5:mod:`gwtransport.diffusion`, :mod:`gwtransport.diffusion_fast`, 

6:mod:`gwtransport.deposition`, and :mod:`gwtransport.residence_time` repeatedly 

7convert a :class:`pandas.DatetimeIndex` of bin edges into a float64 array of 

8days relative to a reference timestamp. The two helpers here factor that 

9idiom once so the conversion (and its object-dtype-on-old-pandas contract) 

10lives in a single place. 

11 

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

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

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

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

16share a common origin. 

17 

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

19plus ``tests/src/test_utils.py``. 

20""" 

21 

22from __future__ import annotations 

23 

24import numpy as np 

25import numpy.typing as npt 

26import pandas as pd 

27 

28 

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

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

31 

32 Parameters 

33 ---------- 

34 tedges : DatetimeIndex 

35 Time-bin edges to convert. 

36 ref : Timestamp or None, optional 

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

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

39 that must align to the same origin. 

40 

41 Returns 

42 ------- 

43 ndarray 

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

45 """ 

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

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

48 

49 

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

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

52 

53 Parameters 

54 ---------- 

55 t : DatetimeIndex 

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

57 

58 Returns 

59 ------- 

60 ndarray 

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

62 """ 

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