geoprior.utils.subsidence_utils#
Utility helpers for subsidence data, units, and coordinates.
Functions
|
Add (or overwrite) subsidence columns in millimeters. |
|
Add columns in the cfg-inferred native unit. |
|
Fix GWL units + robust z_surf, then recompute head_m. |
|
Convert GeoPriorSubsNet evaluation-payload units for reporting. |
|
Convert target-like columns between "m" and "mm". |
|
Recover a rate series from cumulative displacement. |
|
Infer whether subsidence columns represent 'rate', 'cumulative', or an inconsistent pair. |
|
Prevent double SI conversion in GeoPrior scaling_kwargs. |
|
Prevent double SI conversion in GeoPrior scaling_kwargs. |
|
Infer a UTM EPSG code from lon/lat (EPSG:4326). |
|
Convert lon/lat degrees to UTM meters using pyproj. |
|
Build coords tensor (t, x, y) with OPTIONAL shifting (translation only). |
|
Normalize common GWL naming aliases. |
|
Post-hoc convert a Stage-2 evaluation JSON from SI to interpretable units. |
|
Build cumulative displacement from a rate series. |
|
Pick meters GWL for physics; keep z-score ML-only. |
|
Resolve a head column, creating one if needed. |
|
Infer the "native" subsidence unit from cfg. |
|
Subsidence unit->SI factor (to meters). |
Classes
|
- geoprior.utils.subsidence_utils.normalize_gwl_alias(df, gwl_col_user, *, prefer_depth_bgs=True, verbose=True)[source]#
Normalize common GWL naming aliases.
Naming-only: unit conversion happens later.
- geoprior.utils.subsidence_utils.resolve_gwl_for_physics(df, gwl_col_user, *, prefer_depth_bgs=True, allow_keep_zscore_as_ml=True, verbose=True)[source]#
Pick meters GWL for physics; keep z-score ML-only.
- geoprior.utils.subsidence_utils.resolve_head_column(df, *, depth_col, head_col='head_m', z_surf_col=None, use_head_proxy=True)[source]#
Resolve a head column, creating one if needed.
- geoprior.utils.subsidence_utils.convert_target_units_df(df, *, base, from_unit='m', to_unit='mm', mode='overwrite', suffix='_mm', columns=None, unit_col=None, copy_df=True, overwrite_cols=False, strict=False)[source]#
Convert target-like columns between “m” and “mm”.
Selected columns: - base - base + “_*” (quantiles, intervals, …)
If mode=”add”, new columns use suffix.
- geoprior.utils.subsidence_utils.subs_unit_to_si(cfg=None, *, default=0.001, units_prov_key='units_provenance', stage1_key='subs_unit_to_si_applied_stage1', cfg_key='SUBS_UNIT_TO_SI')[source]#
Subsidence unit->SI factor (to meters).
Priority: 1) cfg[units_prov_key][stage1_key] 2) cfg[cfg_key] 3) default
- geoprior.utils.subsidence_utils.subs_native_unit(cfg=None, *, default='mm')[source]#
Infer the “native” subsidence unit from cfg.
unit_to_si ~= 1e-3 -> “mm”
unit_to_si ~= 1.0 -> “m”
- geoprior.utils.subsidence_utils.add_subsidence_mm_columns(df, cfg=None, *, base='subsidence', columns=None, suffix='_mm', unit_col=None, copy_df=True, overwrite=False)[source]#
Add (or overwrite) subsidence columns in millimeters.
Always assumes the current values are in meters.
- geoprior.utils.subsidence_utils.add_subsidence_native_unit_columns(df, cfg=None, *, base='subsidence', columns=None, suffix='_native', unit_col=None, copy_df=True, overwrite=False)[source]#
Add columns in the cfg-inferred native unit.
If cfg says the native unit was meters, this becomes a no-op aside from optional unit_col.
- geoprior.utils.subsidence_utils.finalize_si_scaling_kwargs(scaling_kwargs, *, subs_in_si, head_in_si, thickness_in_si, force_identity_affine_if_si=True, warn=True)[source]#
Prevent double SI conversion in GeoPrior scaling_kwargs.
- geoprior.utils.subsidence_utils.finalize_si_affines_and_units(scaling_kwargs, *, subs_in_si, head_in_si, thickness_in_si, force_identity_affine_if_si=True, warn=True)#
Prevent double SI conversion in GeoPrior scaling_kwargs.
- geoprior.utils.subsidence_utils.infer_utm_epsg_from_lonlat(lon_deg, lat_deg)[source]#
Infer a UTM EPSG code from lon/lat (EPSG:4326).
- Uses standard UTM zoning:
zone = floor((lon + 180)/6) + 1 EPSG = 32600 + zone (north), 32700 + zone (south)
- geoprior.utils.subsidence_utils.lonlat_to_utm_m(lon_deg, lat_deg, *, src_epsg=4326, target_epsg=None)[source]#
Convert lon/lat degrees to UTM meters using pyproj.
- class geoprior.utils.subsidence_utils.CoordsPack(coords: 'np.ndarray', coord_mins: 'dict[str, float]', coord_ranges: 'dict[str, float]', meta: 'dict[str, Any]')[source]#
Bases:
object- Parameters:
- geoprior.utils.subsidence_utils.make_txy_coords(t, x, y, *, time_shift='min', xy_shift='min', time_shift_value=None, x_shift_value=None, y_shift_value=None, dtype='float32')[source]#
Build coords tensor (t, x, y) with OPTIONAL shifting (translation only).
- This is designed for your “not normalized” workflow:
You keep SI units (years and meters),
but you avoid feeding huge UTM magnitudes (e.g. 3e5, 2.5e6) into coord MLPs by shifting x,y (and optionally t).
Notes
This does NOT min-max scale to [0,1]. It only translates.
Returning coord_mins/coord_ranges is still useful for logging/debug.
- geoprior.utils.subsidence_utils.detect_subsidence_mode(df, *, rate_col='subsidence', cum_col='subsidence_cum', time_col='year', group_cols=('longitude', 'latitude', 'city'), tol_rel=0.05, min_points=3, max_groups=200, random_state=42)[source]#
Infer whether subsidence columns represent ‘rate’, ‘cumulative’, or an inconsistent pair.
- geoprior.utils.subsidence_utils.rate_to_cumulative(df, *, rate_col='subsidence', cum_col='subsidence_cum', time_col='year', group_cols=('longitude', 'latitude', 'city'), initial='first_equals_rate_dt', inplace=False)[source]#
Build cumulative displacement from a rate series.
- geoprior.utils.subsidence_utils.cumulative_to_rate(df, *, cum_col='subsidence_cum', rate_col='subsidence', time_col='year', group_cols=('longitude', 'latitude', 'city'), first='cum_over_dtref', inplace=False)[source]#
Recover a rate series from cumulative displacement.
rate(t_i) = (cum(t_i) - cum(t_{i-1})) / dt_i for i>=1
- first:
‘nan’: first rate is NaN
‘cum_over_dtref’: rate(t0) = cum(t0)/dt_ref (dt_ref median dt)
- geoprior.utils.subsidence_utils.convert_eval_payload_units(payload, cfg=None, *, mode='si', scope='all', savefile=None, fmt='json', indent=2, copy_payload=True)[source]#
Convert GeoPriorSubsNet evaluation-payload units for reporting.
This is a post-processing helper meant for stage-2 evaluation JSON payloads (e.g.
geoprior_eval_phys_<timestamp>.json).- Parameters:
payload (
Mapping[str,Any]) – The evaluation payload dict. It is expected to contain sections likemetrics_evaluate,point_metrics,per_horizon,interval_calibrationandcensor_stratified.cfg (
mappingormodule, optional) – The experiment config (e.g.configmodule orglobals()). The helper readsSUBS_UNIT_TO_SI(or stage-1 provenance) andTIME_UNITSfrom this object when available.mode (
{"si", "interpretable"}, default"si") –"si"leaves values untouched."interpretable"converts selected subsidence and physics metrics from SI into the native units implied bySUBS_UNIT_TO_SI.scope (
{"all", "subsidence", "physics"}, default"all") – Which parts to convert whenmode="interpretable"."subsidence"converts only subsidence metrics such as MAE, MSE, and sharpness to the native unit."physics"converts only unambiguous physics residual rates, currentlyepsilon_cons_rawandepsilon_gw_raw."all"applies both conversions.savefile (
str, optional) – If provided, write the converted payload to this path.fmt (
{"json"}, default"json") – Output format whensavefileis provided.indent (
int, default2) – JSON indentation.copy_payload (
bool, defaultTrue) – If True, operate on a deep copy ofpayload. If False, convert in-place (dangerous).
- Returns:
Converted payload as a plain
dict.- Return type:
Notes
For subsidence metrics, linear quantities such as MAE and sharpness scale by
1 / SUBS_UNIT_TO_SI, while squared quantities such as MSE scale by(1 / SUBS_UNIT_TO_SI) ** 2.When physics conversion is enabled,
epsilon_cons_rawis treated as a rate inm/sand converted to<subs_native_unit>/<TIME_UNITS>(for examplemm/yr), whileepsilon_gw_rawis treated as a rate in1/sand converted to1/<TIME_UNITS>.The helper records unit provenance under
payload["units"].
- geoprior.utils.subsidence_utils.clean_gwl_zsurf(df, *, lon_col='longitude', lat_col='latitude', z_col='z_surf', gwl_col='GWL_depth_bgs', gwl_scale='auto', max_depth_m=50.0, z_outlier_iqr_mult=3.0, knn_k=25, return_report=True, savefile=None)[source]#
Fix GWL units + robust z_surf, then recompute head_m.
- geoprior.utils.subsidence_utils.postprocess_eval_json(eval_json, *, cfg=None, scope='all', out_path=None, overwrite=False, add_rmse=True, force=False, indent=2)[source]#
Post-hoc convert a Stage-2 evaluation JSON from SI to interpretable units.
This is a safe wrapper around convert_eval_payload_units(…) that: - loads a JSON from disk (or accepts a payload dict), - infers unit factors from payload[“units”] when cfg is missing, - avoids double conversion unless force=True, - optionally adds RMSE fields (sqrt(MSE)), - writes a converted JSON file if out_path is provided.
- Parameters:
eval_json (str | Mapping[str, Any]) – Either a file path to the saved JSON, or an in-memory mapping.
cfg (Mapping[str, object] | None) – Optional config mapping/module. If missing (or incomplete), this helper will synthesize the minimal keys needed for conversion: - “SUBS_UNIT_TO_SI” - “TIME_UNITS”
scope (Literal['all', 'subsidence', 'physics']) – Forwarded to convert_eval_payload_units(…).
out_path (str | None) – If given, write the converted payload there. If a directory is given, a filename is generated next to the input name (or “geoprior_eval…”).
overwrite (bool) – If False and out_path exists, raise.
add_rmse (bool) – If True, add RMSE fields wherever MSE is present (metrics_evaluate, point_metrics, per_horizon).
force (bool) – If False, skip conversion when payload already declares an interpretable subsidence unit (e.g., “mm”). If True, always convert.
indent (int) – JSON indent used when writing.
- Returns:
The converted payload (always returned as a dict).
- Return type: