{ "cells": [ { "cell_type": "markdown", "id": "d8ba1d9a", "metadata": {}, "source": [ "\n", "# Getting Started: Daily & Monthly Flux Footprints\n", "\n", "This notebook shows how to use **`ffp_daily_monthly_helper.py`** to:\n", "1) load AmeriFlux half‑hourly data, \n", "2) compute an xarray-based footprint climatology, \n", "3) summarize to daily/monthly periods (optionally ET‑weighted), and \n", "4) export **80%** source‑area contours to a GeoPackage or rasters to GeoTIFF.\n", "\n", "References: `ffp_daily_monthly_helper.py`【8†source】 and `ffp_xr.py`【9†source】.\n" ] }, { "cell_type": "markdown", "id": "96c9ab5d", "metadata": {}, "source": [ "\n", "## Requirements\n", "\n", "This workflow uses: `numpy`, `pandas`, `xarray`, `matplotlib`, and for exports `geopandas`, `pyproj`, `shapely`, `rasterio`.\n" ] }, { "cell_type": "code", "execution_count": 1, "id": "04085113", "metadata": { "ExecuteTime": { "end_time": "2025-08-30T01:49:43.629173Z", "start_time": "2025-08-30T01:49:43.613147Z" } }, "outputs": [], "source": [ "\n", "# --- Imports ---\n", "import os\n", "from pathlib import Path\n", "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "import xarray as xr\n", "import sys\n", "\n", "sys.path.append(\"../../src\")\n", "\n", "from fluxfootprints import (\n", " load_config,\n", " load_amf_df,\n", " build_climatology,\n", " summarize_periods,\n", " export_contours_gpkg,\n", " export_rasters_geotiff,\n", " export_contour_stats_csv,\n", ")" ] }, { "cell_type": "markdown", "id": "fbb533d5", "metadata": {}, "source": [ "\n", "## 1) Set Paths\n", "\n", "Update these to point at your AmeriFlux config (`.ini`) and half‑hourly `.csv`.\n" ] }, { "cell_type": "code", "execution_count": 2, "id": "9487e5ba", "metadata": { "ExecuteTime": { "end_time": "2025-08-30T01:35:58.080725Z", "start_time": "2025-08-30T01:35:58.054343Z" } }, "outputs": [], "source": [ "\n", "ini_path = Path(\"./input_data/US-UTE.ini\")\n", "csv_path = Path(\"./input_data/US-UTE_HH_202406241430_202409251400.csv\")\n", "\n", "assert ini_path.exists(), f\"Config not found: {ini_path}\"\n", "assert csv_path.exists(), f\"CSV not found: {csv_path}\"\n", "\n", "out_dir = Path(\"ffp_outputs\")\n", "out_dir.mkdir(parents=True, exist_ok=True)\n" ] }, { "cell_type": "markdown", "id": "3805d386", "metadata": {}, "source": [ "\n", "## 2) Load Configuration & Data\n", "`load_config` parses a minimal INI for site metadata and column mappings. \n", "`load_amf_df` reads the CSV, parses timestamps, sets the index to time, and replaces missing value sentinels【8†source】.\n" ] }, { "cell_type": "code", "execution_count": 3, "id": "c0cb0176", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'station_latitude': 37.7353,\n", " 'station_longitude': -111.5708,\n", " 'missing_data_value': -9999.0,\n", " 'skiprows': 0,\n", " 'date_parser': '%Y%m%d%H%M',\n", " 'ts_col': 'TIMESTAMP_START',\n", " 'wind_dir_col': 'WD',\n", " 'wind_spd_col': 'WS',\n", " 'ustar_col': 'USTAR',\n", " 'mo_length_col': 'MO_LENGTH',\n", " 'v_sigma_col': 'V_SIGMA'}" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "cfg = load_config(str(ini_path))\n", "cfg\n" ] }, { "cell_type": "code", "execution_count": 5, "id": "0381143d", "metadata": {}, "outputs": [ { "data": { "application/vnd.microsoft.datawrangler.viewer.v0+json": { "columns": [ { "name": "TIMESTAMP_START", "rawType": "datetime64[ns]", "type": "datetime" }, { "name": "datetime_start", "rawType": "object", "type": "string" }, { "name": "TIMESTAMP_END", "rawType": "int64", "type": "integer" }, { "name": "CO2", "rawType": "float64", "type": "float" }, { "name": "CO2_SIGMA", "rawType": "float64", "type": "float" }, { "name": "H2O", "rawType": "float64", "type": "float" }, { "name": "H2O_SIGMA", "rawType": "float64", "type": "float" }, { "name": "FC", "rawType": "float64", "type": "float" }, { "name": "FC_SSITC_TEST", "rawType": "float64", "type": "float" }, { "name": "LE", "rawType": "float64", "type": "float" }, { "name": "LE_SSITC_TEST", "rawType": "float64", "type": "float" }, { "name": "ET", "rawType": "float64", "type": "float" }, { "name": "ET_SSITC_TEST", "rawType": "int64", "type": "integer" }, { "name": "H", "rawType": "float64", "type": "float" }, { "name": "H_SSITC_TEST", "rawType": "float64", "type": "float" }, { "name": "G", "rawType": "float64", "type": "float" }, { "name": "SG", "rawType": "float64", "type": "float" }, { "name": "FETCH_MAX", "rawType": "float64", "type": "float" }, { "name": "FETCH_90", "rawType": "float64", "type": "float" }, { "name": "FETCH_55", "rawType": "float64", "type": "float" }, { "name": "FETCH_40", "rawType": "float64", "type": "float" }, { "name": "WD", "rawType": "float64", "type": "float" }, { "name": "WS", "rawType": "float64", "type": "float" }, { "name": "WS_MAX", "rawType": "float64", "type": "float" }, { "name": "USTAR", "rawType": "float64", "type": "float" }, { "name": "ZL", "rawType": "float64", "type": "float" }, { "name": "TAU", "rawType": "float64", "type": "float" }, { "name": "TAU_SSITC_TEST", "rawType": "float64", "type": "float" }, { "name": "MO_LENGTH", "rawType": "float64", "type": "float" }, { "name": "U", "rawType": "float64", "type": "float" }, { "name": "U_SIGMA", "rawType": "float64", "type": "float" }, { "name": "V", "rawType": "float64", "type": "float" }, { "name": "V_SIGMA", "rawType": "float64", "type": "float" }, { "name": "W", "rawType": "float64", "type": "float" }, { "name": "W_SIGMA", "rawType": "float64", "type": "float" }, { "name": "PA", "rawType": "float64", "type": "float" }, { "name": "TA_1_1_1", "rawType": "float64", "type": "float" }, { "name": "RH_1_1_1", "rawType": "float64", "type": "float" }, { "name": "T_DP_1_1_1", "rawType": "float64", "type": "float" }, { "name": "VPD", "rawType": "float64", "type": "float" }, { "name": "T_SONIC", "rawType": "float64", "type": "float" }, { "name": "T_SONIC_SIGMA", "rawType": "float64", "type": "float" }, { "name": "TS_1_1_1", "rawType": "float64", "type": "float" }, { "name": "SWC_1_1_1", "rawType": "float64", "type": "float" }, { "name": "ALB", "rawType": "float64", "type": "float" }, { "name": "NETRAD", "rawType": "float64", "type": "float" }, { "name": "SW_IN", "rawType": "float64", "type": "float" }, { "name": "SW_OUT", "rawType": "float64", "type": "float" }, { "name": "LW_IN", "rawType": "float64", "type": "float" }, { "name": "LW_OUT", "rawType": "float64", "type": "float" }, { "name": "P", "rawType": "float64", "type": "float" }, { "name": "file_no", "rawType": "float64", "type": "float" }, { "name": "TA_1_2_1", "rawType": "float64", "type": "float" }, { "name": "RH_1_2_1", "rawType": "float64", "type": "float" }, { "name": "T_DP_1_2_1", "rawType": "float64", "type": "float" }, { "name": "TA_1_3_1", "rawType": "float64", "type": "float" }, { "name": "RH_1_3_1", "rawType": "float64", "type": "float" }, { "name": "T_DP_1_3_1", "rawType": "float64", "type": "float" }, { "name": "TA_1_4_1", "rawType": "float64", "type": "float" }, { "name": "PBLH_F", "rawType": "float64", "type": "float" }, { "name": "TS_2_1_1", "rawType": "float64", "type": "float" }, { "name": "SWC_2_1_1", "rawType": "float64", "type": "float" } ], "ref": "e1b3d041-6321-4d48-81d8-a7a24fd0487a", "rows": [ [ "2024-06-24 14:30:00", "2024-06-24 14:30:00", "202406241500", "427.0199", "0.6281331", "17.26862", "1.01929", "0.0692101", null, "156.4085", null, "0.2317847", "1", "68.15252", null, "74.8003", "46.48377", "20.10258", "55.5867", "28.58118", "21.63193", "83.82242", "4.118659", "11.398", "0.2854266", "-0.1000675", "-0.07743155", null, "-21.72663", "3.943613", "1.289412", "0.0", "1.243537", "0.0", "0.5457488", "83.32956", "30.37961", "32.53116", "12.07391", "28.36929", "31.6011", "0.7804169", "22.91248", null, "30.47296", "535.9557", "901.6483", "279.5316", "404.7657", "490.9268", "0.0", "2.0", "29.95141", "33.26877", "12.0526", "30.32464", "33.45364", "12.46181", "30.06976", "1665.467", "25.72815", "22.44161" ], [ "2024-06-24 15:00:00", "2024-06-24 15:00:00", "202406241530", "425.9499", "1.019297", "15.18936", "0.7030515", "0.2854458", null, "138.3092", null, "0.20497", "1", "43.44571", null, "-11.26564", "-34.50821", "19.01147", "52.56938", "27.02798", "20.45655", "84.50763", "3.128728", "8.11528", "0.2287946", "-0.130162", "-0.04976684", null, "-16.70326", "2.949647", "1.087555", "0.0", "1.085609", "3.72529e-09", "0.4690718", "83.3021", "30.43124", "28.59812", "10.17519", "30.22208", "31.47819", "0.6128186", "22.98583", null, "31.01464", "404.8066", "711.1035", "227.3555", "407.2817", "486.2231", "0.0", "2.0", "30.02516", "29.22197", "10.15524", "30.35956", "29.77183", "10.72635", "30.13765", "1765.935", "25.52736", "22.41975" ], [ "2024-06-24 15:30:00", "2024-06-24 15:30:00", "202406241600", "426.4163", "1.965228", "14.87533", "0.8080265", "1.081928", null, "154.1153", null, "0.2284687", "2", "30.66234", null, "-41.83331", "-63.57699", "24.54221", "67.84465", "34.89815", "26.41252", "98.6839", "2.669845", "6.715653", "0.2784614", "-0.05601415", "-0.07362495", "1.0", "-38.81393", "2.517204", "0.9474617", "0.0", "0.9015959", "3.72529e-09", "0.4148929", "83.27771", "30.85518", "27.38244", "9.86806", "31.03824", "31.67058", "0.7545337", "23.08474", null, "29.70208", "292.8351", "546.4703", "175.4796", "408.3091", "486.4648", "0.0", "2.0", "30.24634", "28.28498", "9.838229", "30.69433", "28.63222", "10.41335", "30.40344", "1495.735", "25.12511", "22.32785" ], [ "2024-06-24 16:00:00", "2024-06-24 16:00:00", "202406241630", "426.0534", "2.665907", "15.6114", "1.002919", "0.5196642", null, "135.5618", null, "0.2010524", "2", "35.2179", null, "-35.91724", "-55.3435", "25.22658", "69.73144", "35.87147", "27.14916", "99.19427", "2.552504", "7.758736", "0.307955", "-0.04485384", "-0.08986875", null, "-48.47143", "2.415924", "0.9642583", "0.0", "0.8306037", "7.450581e-09", "0.4433303", "83.25893", "31.35262", "27.86196", "10.56774", "31.70765", "32.24849", "0.7409122", "23.06612", null, "31.21184", "331.988", "619.2519", "209.6434", "410.9713", "488.5918", "0.0", "2.0", "30.75179", "28.75255", "10.53822", "31.14621", "29.16225", "11.09066", "30.90061", "1491.062", "24.63557", "22.18172" ], [ "2024-06-24 16:30:00", "2024-06-24 16:30:00", "202406241700", "427.8476", "1.102921", "15.21034", "0.7030841", "1.147608", null, "95.06287", null, "0.1407727", "2", "-13.31553", null, "-56.61974", "-71.7462", "26.52178", "74.34869", "37.88823", "28.65891", "115.6484", "1.786293", "6.475121", "0.3013755", "0.007892104", "-0.08651999", null, "275.4816", "1.65628", "0.8001992", "0.0", "0.6585423", "-9.313226e-10", "0.4075378", "83.24686", "29.68962", "29.8947", "10.19186", "28.14444", "30.6135", "0.5463738", "22.7616", null, "28.93153", "79.40314", "209.7798", "67.09201", "404.4651", "467.7497", "0.0", "2.0", "29.16274", "30.77158", "10.16581", "29.57434", "30.96792", "10.63069", "29.3051", "341.9711", "24.14865", "22.03216" ] ], "shape": { "columns": 61, "rows": 5 } }, "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
datetime_startTIMESTAMP_ENDCO2CO2_SIGMAH2OH2O_SIGMAFCFC_SSITC_TESTLELE_SSITC_TEST...TA_1_2_1RH_1_2_1T_DP_1_2_1TA_1_3_1RH_1_3_1T_DP_1_3_1TA_1_4_1PBLH_FTS_2_1_1SWC_2_1_1
TIMESTAMP_START
2024-06-24 14:30:002024-06-24 14:30:00202406241500427.01990.62813317.268621.0192900.069210NaN156.40850NaN...29.9514133.2687712.05260030.3246433.4536412.4618130.069761665.467025.7281522.44161
2024-06-24 15:00:002024-06-24 15:00:00202406241530425.94991.01929715.189360.7030520.285446NaN138.30920NaN...30.0251629.2219710.15524030.3595629.7718310.7263530.137651765.935025.5273622.41975
2024-06-24 15:30:002024-06-24 15:30:00202406241600426.41631.96522814.875330.8080261.081928NaN154.11530NaN...30.2463428.284989.83822930.6943328.6322210.4133530.403441495.735025.1251122.32785
2024-06-24 16:00:002024-06-24 16:00:00202406241630426.05342.66590715.611401.0029190.519664NaN135.56180NaN...30.7517928.7525510.53822031.1462129.1622511.0906630.900611491.062024.6355722.18172
2024-06-24 16:30:002024-06-24 16:30:00202406241700427.84761.10292115.210340.7030841.147608NaN95.06287NaN...29.1627430.7715810.16581029.5743430.9679210.6306929.30510341.971124.1486522.03216
\n", "

5 rows × 61 columns

\n", "
" ], "text/plain": [ " datetime_start TIMESTAMP_END CO2 CO2_SIGMA \\\n", "TIMESTAMP_START \n", "2024-06-24 14:30:00 2024-06-24 14:30:00 202406241500 427.0199 0.628133 \n", "2024-06-24 15:00:00 2024-06-24 15:00:00 202406241530 425.9499 1.019297 \n", "2024-06-24 15:30:00 2024-06-24 15:30:00 202406241600 426.4163 1.965228 \n", "2024-06-24 16:00:00 2024-06-24 16:00:00 202406241630 426.0534 2.665907 \n", "2024-06-24 16:30:00 2024-06-24 16:30:00 202406241700 427.8476 1.102921 \n", "\n", " H2O H2O_SIGMA FC FC_SSITC_TEST LE \\\n", "TIMESTAMP_START \n", "2024-06-24 14:30:00 17.26862 1.019290 0.069210 NaN 156.40850 \n", "2024-06-24 15:00:00 15.18936 0.703052 0.285446 NaN 138.30920 \n", "2024-06-24 15:30:00 14.87533 0.808026 1.081928 NaN 154.11530 \n", "2024-06-24 16:00:00 15.61140 1.002919 0.519664 NaN 135.56180 \n", "2024-06-24 16:30:00 15.21034 0.703084 1.147608 NaN 95.06287 \n", "\n", " LE_SSITC_TEST ... TA_1_2_1 RH_1_2_1 T_DP_1_2_1 \\\n", "TIMESTAMP_START ... \n", "2024-06-24 14:30:00 NaN ... 29.95141 33.26877 12.052600 \n", "2024-06-24 15:00:00 NaN ... 30.02516 29.22197 10.155240 \n", "2024-06-24 15:30:00 NaN ... 30.24634 28.28498 9.838229 \n", "2024-06-24 16:00:00 NaN ... 30.75179 28.75255 10.538220 \n", "2024-06-24 16:30:00 NaN ... 29.16274 30.77158 10.165810 \n", "\n", " TA_1_3_1 RH_1_3_1 T_DP_1_3_1 TA_1_4_1 PBLH_F \\\n", "TIMESTAMP_START \n", "2024-06-24 14:30:00 30.32464 33.45364 12.46181 30.06976 1665.4670 \n", "2024-06-24 15:00:00 30.35956 29.77183 10.72635 30.13765 1765.9350 \n", "2024-06-24 15:30:00 30.69433 28.63222 10.41335 30.40344 1495.7350 \n", "2024-06-24 16:00:00 31.14621 29.16225 11.09066 30.90061 1491.0620 \n", "2024-06-24 16:30:00 29.57434 30.96792 10.63069 29.30510 341.9711 \n", "\n", " TS_2_1_1 SWC_2_1_1 \n", "TIMESTAMP_START \n", "2024-06-24 14:30:00 25.72815 22.44161 \n", "2024-06-24 15:00:00 25.52736 22.41975 \n", "2024-06-24 15:30:00 25.12511 22.32785 \n", "2024-06-24 16:00:00 24.63557 22.18172 \n", "2024-06-24 16:30:00 24.14865 22.03216 \n", "\n", "[5 rows x 61 columns]" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Time span: 2024-06-24 14:30:00 → 2024-09-25 13:30:00 | rows: 4463\n" ] } ], "source": [ "\n", "df = load_amf_df(str(csv_path), cfg)\n", "display(df.head())\n", "print(\"Time span:\", df.index.min(), \"→\", df.index.max(), \"| rows:\", len(df))\n" ] }, { "cell_type": "markdown", "id": "48ef2dd0", "metadata": {}, "source": [ "\n", "## 3) Build the Footprint Climatology\n", "`build_climatology` renames expected AMF columns (WD, WS, USTAR, MO_LENGTH, V_SIGMA) to the solver’s names and runs the **xarray-based** climatology (`ffp_xr.ffp_climatology_new.run()`), filling `clim.f_2d` with per‑timestep footprints【8†source】【9†source】.\n" ] }, { "cell_type": "code", "execution_count": 6, "id": "ab09093e", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "c:\\Users\\paulinkenbrandt\\.conda\\envs\\py313\\Lib\\site-packages\\xarray\\core\\computation.py:824: RuntimeWarning: overflow encountered in exp\n", " result_data = func(*input_data)\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "clim = build_climatology(\n", " df,\n", " crop_height=0.2,\n", " atm_bound_height=2000.0,\n", " inst_height=2.5,\n", " dx=10.0, dy=10.0,\n", " domain=(-500.0, 500.0, -500.0, 500.0), # smaller domain for a quick start\n", ")\n", "clim\n" ] }, { "cell_type": "markdown", "id": "a4d51fb9", "metadata": {}, "source": [ "\n", "## 4) Summarize to Daily / Monthly\n", "- `summarize_periods` normalizes each time slice so that the sum over x,y = 1 (optional), then computes:\n", " - **Daily/Monthly means**, and\n", " - **ET‑weighted** versions using ET derived from LE (mm/hr = LE / 680.6)【8†source】.\n" ] }, { "cell_type": "code", "execution_count": 7, "id": "44b94593", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "SummaryResult(f_daily_mean= Size: 8MB\n", "array([[[3.58529140e-25, 2.47120712e-25, 1.30180180e-25, ...,\n", " 1.15227703e-06, 1.12684997e-06, 1.10643026e-06],\n", " [1.61688067e-24, 1.13370153e-24, 6.17743647e-25, ...,\n", " 1.17094169e-06, 1.13943374e-06, 1.11496572e-06],\n", " [8.02980544e-24, 5.72022119e-24, 3.21445865e-24, ...,\n", " 1.19367042e-06, 1.15319902e-06, 1.12281202e-06],\n", " ...,\n", " [7.89861902e-07, 8.66178271e-07, 9.85317157e-07, ...,\n", " 1.91956888e-09, 1.24349142e-09, 8.91069420e-10],\n", " [8.39947197e-07, 9.18133265e-07, 1.03986243e-06, ...,\n", " 2.39246383e-09, 1.56477140e-09, 1.13021861e-09],\n", " [8.73933879e-07, 9.53281685e-07, 1.07660354e-06, ...,\n", " 2.75318461e-09, 1.81129648e-09, 1.31460274e-09]],\n", "\n", " [[6.00464387e-08, 6.93686910e-08, 8.59536570e-08, ...,\n", " 8.36127401e-07, 7.71296111e-07, 7.25343010e-07],\n", " [5.76548590e-08, 6.56121274e-08, 8.00248469e-08, ...,\n", " 8.22083250e-07, 7.52786949e-07, 7.04452223e-07],\n", " [5.55611358e-08, 6.16154009e-08, 7.29662722e-08, ...,\n", " 7.97210851e-07, 7.22668506e-07, 6.71809732e-07],\n", "...\n", " 3.14213432e-12, 5.17393930e-12, 6.98117705e-12],\n", " [2.48316745e-07, 2.78140787e-07, 3.25240203e-07, ...,\n", " 1.27922703e-12, 2.14997600e-12, 2.93312486e-12],\n", " [2.63565473e-07, 2.94387970e-07, 3.42924024e-07, ...,\n", " 5.96797930e-13, 1.02287541e-12, 1.41009881e-12]],\n", "\n", " [[3.16442287e-29, 2.07756927e-29, 9.92754305e-30, ...,\n", " 1.34459763e-06, 1.22274851e-06, 1.14983677e-06],\n", " [2.02359675e-28, 1.35045737e-28, 6.67401798e-29, ...,\n", " 1.32218080e-06, 1.21299288e-06, 1.14930747e-06],\n", " [1.38384239e-27, 9.37663921e-28, 4.77930180e-28, ...,\n", " 1.30043662e-06, 1.21045092e-06, 1.16003900e-06],\n", " ...,\n", " [2.61500741e-11, 3.95106174e-11, 6.69961469e-11, ...,\n", " 1.04762465e-32, 9.02016196e-34, 7.82860133e-35],\n", " [3.43706349e-11, 5.14967973e-11, 8.64417171e-11, ...,\n", " 2.37573980e-32, 2.12353051e-33, 1.91994542e-34],\n", " [4.08616336e-11, 6.09039460e-11, 1.01599559e-10, ...,\n", " 3.75726787e-32, 3.41639807e-33, 3.14638746e-34]]],\n", " shape=(94, 101, 101))\n", "Coordinates:\n", " * x (x) float64 808B -500.0 -490.0 -480.0 -470.0 ... 480.0 490.0 500.0\n", " * y (y) float64 808B -500.0 -490.0 -480.0 -470.0 ... 480.0 490.0 500.0\n", " * time (time) datetime64[ns] 752B 2024-06-24 2024-06-25 ... 2024-09-25, f_monthly_mean= Size: 326kB\n", "array([[[8.10510828e-07, 8.32705618e-07, 8.66003392e-07, ...,\n", " 6.10293228e-07, 5.89428859e-07, 5.75683345e-07],\n", " [8.20011752e-07, 8.42840319e-07, 8.77047518e-07, ...,\n", " 6.20466844e-07, 5.99977115e-07, 5.86696874e-07],\n", " [8.33773596e-07, 8.57527474e-07, 8.93099934e-07, ...,\n", " 6.36693265e-07, 6.17054153e-07, 6.04581333e-07],\n", " ...,\n", " [8.36745096e-07, 8.82601266e-07, 9.53745251e-07, ...,\n", " 3.98781353e-09, 2.82500111e-09, 2.19225588e-09],\n", " [8.48915359e-07, 8.95735762e-07, 9.68021381e-07, ...,\n", " 4.85582157e-09, 3.44132268e-09, 2.66227747e-09],\n", " [8.57641484e-07, 9.05001225e-07, 9.77869817e-07, ...,\n", " 5.52079346e-09, 3.92153975e-09, 3.03476439e-09]],\n", "\n", " [[5.07956744e-07, 5.23480705e-07, 5.47241803e-07, ...,\n", " 5.95632676e-07, 5.80325054e-07, 5.70417943e-07],\n", " [5.13159969e-07, 5.28725276e-07, 5.52536276e-07, ...,\n", " 6.09337933e-07, 5.94032427e-07, 5.84105849e-07],\n", " [5.21123290e-07, 5.36751599e-07, 5.60646350e-07, ...,\n", " 6.30248106e-07, 6.14821698e-07, 6.04754554e-07],\n", "...\n", " 8.76655203e-08, 8.52108402e-08, 8.34469755e-08],\n", " [9.89793700e-07, 1.01533439e-06, 1.05447861e-06, ...,\n", " 8.47431952e-08, 8.26748120e-08, 8.11771385e-08],\n", " [9.74356013e-07, 9.99851206e-07, 1.03888352e-06, ...,\n", " 8.26780863e-08, 8.08620673e-08, 7.95464388e-08]],\n", "\n", " [[7.95674211e-07, 8.17429635e-07, 8.48020398e-07, ...,\n", " 7.48942523e-07, 7.06731501e-07, 6.79480477e-07],\n", " [8.00105939e-07, 8.23919460e-07, 8.57540738e-07, ...,\n", " 7.49730417e-07, 7.08218660e-07, 6.81533409e-07],\n", " [8.04225877e-07, 8.31050416e-07, 8.69187806e-07, ...,\n", " 7.51709785e-07, 7.11310410e-07, 6.85435066e-07],\n", " ...,\n", " [7.17721830e-07, 7.52958488e-07, 8.07412112e-07, ...,\n", " 3.93268661e-08, 3.65701505e-08, 3.47342303e-08],\n", " [7.24507387e-07, 7.60311034e-07, 8.15314865e-07, ...,\n", " 3.98906134e-08, 3.72056105e-08, 3.54119707e-08],\n", " [7.29481333e-07, 7.65533538e-07, 8.20710773e-07, ...,\n", " 4.02336888e-08, 3.76019678e-08, 3.58406427e-08]]],\n", " shape=(4, 101, 101))\n", "Coordinates:\n", " * x (x) float64 808B -500.0 -490.0 -480.0 -470.0 ... 480.0 490.0 500.0\n", " * y (y) float64 808B -500.0 -490.0 -480.0 -470.0 ... 480.0 490.0 500.0\n", " * time (time) datetime64[ns] 32B 2024-06-01 2024-07-01 ... 2024-09-01, f_daily_et_weighted= Size: 8MB\n", "array([[[ 3.04594887e-25, 2.09945851e-25, 1.10596916e-25, ...,\n", " 1.46791745e-06, 1.43552331e-06, 1.40950863e-06],\n", " [ 1.37365009e-24, 9.63156549e-25, 5.24815239e-25, ...,\n", " 1.49169187e-06, 1.45155039e-06, 1.42037789e-06],\n", " [ 6.82186581e-24, 4.85971692e-24, 2.73090123e-24, ...,\n", " 1.52064054e-06, 1.46907889e-06, 1.43036503e-06],\n", " ...,\n", " [ 2.99540133e-08, 3.40140388e-08, 4.06101071e-08, ...,\n", " 2.53970948e-09, 1.64521754e-09, 1.17894155e-09],\n", " [ 3.26505673e-08, 3.69868128e-08, 4.40083117e-08, ...,\n", " 3.16537844e-09, 2.07029050e-09, 1.49535031e-09],\n", " [ 3.45535794e-08, 3.90779920e-08, 4.63885062e-08, ...,\n", " 3.64263422e-09, 2.39645835e-09, 1.73930183e-09]],\n", "\n", " [[ 4.48064581e-08, 4.14789404e-08, 3.66749003e-08, ...,\n", " 2.07247549e-06, 1.90863314e-06, 1.79230921e-06],\n", " [ 5.18785662e-08, 4.82704131e-08, 4.30632994e-08, ...,\n", " 2.03473279e-06, 1.85926363e-06, 1.73667888e-06],\n", " [ 6.32913591e-08, 5.92471957e-08, 5.34108320e-08, ...,\n", " 1.96805460e-06, 1.77878965e-06, 1.64944952e-06],\n", "...\n", " 9.40777249e-12, 1.54911403e-11, 2.09021380e-11],\n", " [-9.19200690e-09, -9.69012229e-09, -1.02817102e-08, ...,\n", " 3.83009624e-12, 6.43718026e-12, 8.78198335e-12],\n", " [-9.52182045e-09, -9.96865891e-09, -1.04608744e-08, ...,\n", " 1.78685523e-12, 3.06256136e-12, 4.22193561e-12]],\n", "\n", " [[ 6.68905595e-29, 4.39163085e-29, 2.09851508e-29, ...,\n", " 2.96446272e-06, 2.69858543e-06, 2.53945096e-06],\n", " [ 4.27754204e-28, 2.85463900e-28, 1.41077478e-28, ...,\n", " 2.91674515e-06, 2.67855559e-06, 2.53964592e-06],\n", " [ 2.92520929e-27, 1.98206330e-27, 1.01026375e-27, ...,\n", " 2.87122226e-06, 2.67508189e-06, 2.56528548e-06],\n", " ...,\n", " [ 4.52261520e-11, 6.83185976e-11, 1.15828237e-10, ...,\n", " 1.73373135e-32, 1.50682042e-33, 1.31741803e-34],\n", " [ 5.94259144e-11, 8.90302434e-11, 1.49437706e-10, ...,\n", " 3.91184630e-32, 3.53473416e-33, 3.22310012e-34],\n", " [ 7.06425914e-11, 1.05288993e-10, 1.75638821e-10, ...,\n", " 6.17085198e-32, 5.67671519e-33, 5.27574171e-34]]],\n", " shape=(94, 101, 101))\n", "Coordinates:\n", " * x (x) float64 808B -500.0 -490.0 -480.0 -470.0 ... 480.0 490.0 500.0\n", " * y (y) float64 808B -500.0 -490.0 -480.0 -470.0 ... 480.0 490.0 500.0\n", " * time (time) datetime64[ns] 752B 2024-06-24 2024-06-25 ... 2024-09-25, f_monthly_et_weighted= Size: 326kB\n", "array([[[1.06678502e-06, 1.09543191e-06, 1.13890285e-06, ...,\n", " 1.36145583e-06, 1.31384375e-06, 1.28277527e-06],\n", " [1.07954128e-06, 1.10903506e-06, 1.15352918e-06, ...,\n", " 1.38490337e-06, 1.33869784e-06, 1.30911702e-06],\n", " [1.09752490e-06, 1.12843535e-06, 1.17473956e-06, ...,\n", " 1.42284669e-06, 1.37950445e-06, 1.35246000e-06],\n", " ...,\n", " [4.91780005e-07, 5.04102371e-07, 5.23536436e-07, ...,\n", " 5.03916543e-10, 3.70607384e-10, 2.99670687e-10],\n", " [4.79172922e-07, 4.92079703e-07, 5.12205039e-07, ...,\n", " 5.90723007e-10, 4.27092725e-10, 3.38388323e-10],\n", " [4.71350181e-07, 4.84603293e-07, 5.05095668e-07, ...,\n", " 6.59175505e-10, 4.73656472e-10, 3.72164520e-10]],\n", "\n", " [[1.45042039e-06, 1.49810925e-06, 1.56827210e-06, ...,\n", " 9.13166954e-07, 8.84874074e-07, 8.66200239e-07],\n", " [1.45644152e-06, 1.50593754e-06, 1.57893653e-06, ...,\n", " 9.30163477e-07, 9.01292895e-07, 8.82182013e-07],\n", " [1.46373500e-06, 1.51575543e-06, 1.59277328e-06, ...,\n", " 9.55514109e-07, 9.25590171e-07, 9.05676691e-07],\n", "...\n", " 7.56016564e-08, 7.28841109e-08, 7.10660994e-08],\n", " [7.36933822e-07, 7.52405244e-07, 7.75549812e-07, ...,\n", " 7.38626585e-08, 7.12424102e-08, 6.94861255e-08],\n", " [7.22732033e-07, 7.37960461e-07, 7.60547330e-07, ...,\n", " 7.26962654e-08, 7.01465276e-08, 6.84391957e-08]],\n", "\n", " [[1.40309305e-06, 1.45293405e-06, 1.52489386e-06, ...,\n", " 1.41182608e-06, 1.32986666e-06, 1.27725375e-06],\n", " [1.40138757e-06, 1.45420235e-06, 1.53068956e-06, ...,\n", " 1.41224133e-06, 1.33217019e-06, 1.28101009e-06],\n", " [1.39534679e-06, 1.45236694e-06, 1.53538818e-06, ...,\n", " 1.41491160e-06, 1.33773786e-06, 1.28861440e-06],\n", " ...,\n", " [5.23979932e-07, 5.45416401e-07, 5.77317462e-07, ...,\n", " 3.30962489e-08, 2.95098753e-08, 2.71874150e-08],\n", " [5.25481920e-07, 5.46089808e-07, 5.76502095e-07, ...,\n", " 3.47163663e-08, 3.10696461e-08, 2.86938616e-08],\n", " [5.26152613e-07, 5.46082717e-07, 5.75331480e-07, ...,\n", " 3.58102628e-08, 3.21350883e-08, 2.97314605e-08]]],\n", " shape=(4, 101, 101))\n", "Coordinates:\n", " * x (x) float64 808B -500.0 -490.0 -480.0 -470.0 ... 480.0 490.0 500.0\n", " * y (y) float64 808B -500.0 -490.0 -480.0 -470.0 ... 480.0 490.0 500.0\n", " * time (time) datetime64[ns] 32B 2024-06-01 2024-07-01 ... 2024-09-01)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "summaries = summarize_periods(\n", " clim,\n", " df,\n", " et_source=\"LE\", # use LE (W/m^2) to derive ET weights\n", " daily=True,\n", " monthly=True,\n", " normalize_each_time=True,\n", ")\n", "summaries\n" ] }, { "cell_type": "markdown", "id": "7780cea3", "metadata": {}, "source": [ "\n", "## 5) Quick Visualization\n", "\n", "Plot the first available **daily mean** footprint. \n", "(Uses `matplotlib`; ensure you keep a single plot per figure and default colors.)\n" ] }, { "cell_type": "code", "execution_count": 8, "id": "75fda4f4", "metadata": {}, "outputs": [ { "data": { "image/png": "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Ha398ccfeO211/DDDz9oPK/rmB0TTKkgIiIiUjdt2jTcvn0bJ06cgJ2dHX788Uds3rwZrVq1wjfffKNzuWzZISIiMiIOUNbeTz/9hN27d+Ppp5+GhYUFvL290atXLzg6OiImJgb9+/fXqVy27BCRcQlhmIOorhIGOuqBe/fuoUmTJgAebCPxxx9/AHiwoejZs2d1LpfBDhEREdUKTzzxBK5evQoA6NChA/79738jPT0da9euRdOmTXUul91YRERERsRuLO1NmzYNmZmZAID58+ejd+/e+Oyzz2BjY4NNmzbpXC6DHSIiImPibCytvfzyy9LPHTt2xPXr1/HLL7+gefPmcHNz07lcBjtERERUKzVo0ACdOnXSuxwGO0RERMbElh2tCSHw5Zdf4uDBg8jOzoZKJd+H76uvvtKpXAY7RERERsQxO9qbOnUqPv74Y3Tv3h3u7u4P3SBUWwx2iIiIqFb49NNP8dVXX6Ffv34GLZfBDhERkTGxG0trTk5OaNGihcHL5To7RERExsRFBbUWFRWFBQsW4P79+wYtly07REREVCu89NJL2LZtG5o0aQIfHx9YW1vLzuu6ijKDHSIiIiPiAGXthYeHIykpCa+88goHKBMREdUZHLOjte+//x579+7Fc889Z9ByOWaHiIiIagUvLy84OjoavFwGO0REREZU3o2l71EffPjhh5g5cyauX79u0HLZjUVERGRM7MbS2iuvvIKCggL4+fmhQYMGagOU//zzT53KZbBDREREtUJsbKxRymWwQ0REZExs2dFKSUkJEhIS8M477xh8YUGO2SEiIjIihYEOc2dtbY1du3YZpWwGO0RERFQrDBkyBF9//bXBy2U3FhERkTGxG0trLVu2xHvvvYfjx48jICAA9vb2svNTpkzRqVwGO0REREbEFZS198knn6BRo0ZISkpCUlKS7JxCoWCwQ0RERHVbSkqKUcplsENERGRM7MbSiRAPHtoQ+2NxgDIREZGxCT2PemTLli1o164d7OzsYGdnh/bt22Pr1q16lcmWHSIiIqoVli9fjnfeeQeTJ09Gly5dIITAsWPHEBERgZycHEyfPl2nchnsEBERGREHKGtv5cqVWLNmDV599VUpbdCgQWjbti2ioqIY7BAREdVKHLOjtczMTAQHB6ulBwcHIzMzU+dyOWaHiIiIaoWWLVviiy++UEvfsWMHWrVqpXO5bNkhIiIyInZjaW/BggUYPnw4Dh8+jC5dukChUODo0aM4cOCAxiBIWwx2iIiIjIndWFobOnQoTp48iY8++ghff/01hBBo06YNTp06hY4dO+pcLoMdIiIiqjUCAgLw6aefGrRMBjtERERGxG4s02OwQ0REZEzsxnooCwuLh66UrFAoUFpaqlP5DHaIiIjIpHbt2lXluePHj2PlypXS9hG6YLBDRERkTGzZeahBgwappf3yyy+YM2cOvv32W7z88st47733dC6f6+wQEREZUfmYHX2P+iIjIwMTJkxA+/btUVpainPnzmHz5s1o3ry5zmUy2CEiIiKTy8vLw6xZs9CyZUtcunQJBw4cwLfffgt/f3+9y2Y3FhERkTGxG+uhlixZgg8++AAeHh7Ytm2bxm4tfdSJlp3r169j3Lhx8PX1hZ2dHfz8/DB//nwUFxfL8qWmpmLgwIGwt7eHm5sbpkyZopbnwoULCA0NhZ2dHR577DEsXLhQr0FPRERE1VEIYZDDnM2ePRuFhYVo2bIlNm/ejBdeeEHjoas6Eez88ssvUKlU+Pe//41Lly7ho48+wtq1azF37lwpT1lZGfr374979+7h6NGj2L59O3bu3Im33npLypOfn49evXrB09MTp0+fxsqVK7Fs2TIsX77cFI9FRERkVHFxcfD19YWtrS0CAgJw5MiRavMfOnQIAQEBsLW1RYsWLbB27VrZ+UuXLmHo0KHw8fGBQqFAbGysQe776quvYtiwYXBxcYGTk1OVh67qRDdWnz590KdPH+lzixYtcPXqVaxZswbLli0DAOzbtw+XL19GWloaPD09AQAffvghwsPD8f7778PR0RGfffYZCgsLsWnTJiiVSvj7++PXX3/F8uXLERkZ+dA5/kRERDVmom6sHTt2YNq0aYiLi0OXLl3w73//G3379sXly5c1DvZNSUlBv379MGHCBHz66ac4duwYJk6ciMaNG2Po0KEAgIKCArRo0QIvvfQSpk+fbpD7AsCmTZtq/oA1UCdadjTJy8uDi4uL9DkxMRH+/v5SoAMAvXv3RlFREZKSkqQ8oaGhUCqVsjwZGRm4fv16lfcqKipCfn6+7CAiItKGqWZjLV++HOPGjcP48ePRunVrxMbGwsvLC2vWrNGYf+3atWjevDliY2PRunVrjB8/HmPHjpUaFQDg6aefxtKlSzFixAjZv6X63PdRqJPBzm+//YaVK1ciIiJCSsvKyoK7u7ssn7OzM2xsbJCVlVVlnvLP5Xk0iYmJkTWjeXl5GepRiIiItFb5i3dRUZHGfMXFxUhKSkJYWJgsPSwsDMePH9d4TWJiolr+3r1748yZMygpKdGqfrrc91EwabATFRUFhUJR7XHmzBnZNRkZGejTpw9eeukljB8/XnZOUzeUEEKWXjlP+eDk6rqw5syZg7y8POlIS0ur8bMSEVE9JQx0APDy8pJ9+Y6JidF4y5ycHJSVlWn8gl/Vl/uqGgRKS0uRk5Oj1aPqct9HwaRjdiZPnowRI0ZUm8fHx0f6OSMjA927d0dQUBA+/vhjWT4PDw+cPHlSlnb79m2UlJRIL93Dw0PtZWdnZwOA2v+YipRKZZXNdURERNUx5EagaWlpcHR0lNIf9m+Tpi/41X2516VBwBD3NTaTBjtubm5wc3PTKm96ejq6d++OgIAAbNy4ERYW8kapoKAgvP/++8jMzETTpk0BPBi0rFQqERAQIOWZO3cuiouLYWNjI+Xx9PSUBVVERES1kaOjoyzYqYqbmxssLS01fsGv6st9VQ0CVlZWcHV11ap+utz3UagTY3YyMjLQrVs3eHl5YdmyZfjjjz+QlZUle5lhYWFo06YNRo8ejeTkZBw4cAAzZszAhAkTpF+MUaNGQalUIjw8HBcvXsSuXbsQHR3NmVhERGQ8BuzG0paNjQ0CAgIQHx8vS4+Pj0dwcLDGa4KCgtTy79u3D4GBgbC2tjbafR+FOjH1fN++ffjvf/+L//73v2jWrJnsXHkTm6WlJb7//ntMnDgRXbp0gZ2dHUaNGiUbRe7k5IT4+HhMmjQJgYGBcHZ2RmRkJCIjIx/p8xARUf1hyG6smoiMjMTo0aMRGBgoDf9ITU2VJvfMmTMH6enp2LJlCwAgIiICq1atQmRkJCZMmIDExESsX78e27Ztk8osLi7G5cuXpZ/T09Nx7tw5NGzYEC1bttTqvqagEFw+uMby8/Ph5OSEbhgEK4V20S4REdU+paIECdiNvLw8rbqHaqL834qA4e/D0sZWr7LKiguRtGNejesZFxeHJUuWIDMzE/7+/vjoo4/QtWtXAEB4eDiuX7+OhIQEKf+hQ4cwffp0XLp0CZ6enpg1a5YsSLl+/Tp8fX3V7hMaGiorp7r7mgKDHR0w2CEiMg+PJNgZZqBg54uaBzv0QJ3oxiIiIqrL9O3GIv3UiQHKRERERLpiyw4REZExCfHg0LcM0hmDHSIiIiMy1Wws+hu7sYiIiMissWWHiIjImHRYFFBjGaQzBjtERERGpFA9OPQtg3THbiwiIiIya2zZISIiMiZ2Y5kcgx0iIiIj4mws02M3FhEREZk1tuwQEREZExcVNDkGO0REREbEbizTYzcWERERmTW27BARERkTZ2OZHIMdIiIiI2I3lumxG4uIiIjMGlt2iIiIjImzsUyOwQ4REZERsRvL9NiNRURERGaNLTtERETGxNlYJsdgh4iIyIjYjWV67MYiIiIis8aWHSIiImNSiQeHvmWQzhjsEBERGRPH7Jgcu7GIiIjIrLFlh4iIyIgUMMAAZYPUpP5iyw4RERGZNbbsEBERGRO3izA5BjtERERGxHV2TI/dWERERGTW2LJDRERkTJx6bnIMdoiIiIxIIQQUeo650ff6+o7dWERERGTW2LJDRERkTKr/HfqWQTpjsENERGRE7MYyPXZjERERkVljyw4REZExcTaWyTHYISIiMiauoGxy7MYiIiIis8aWHSIiIiPidhGmx2CHiIjImNiNZXLsxiIiIiKzxpYdIiIiI1KoHhz6lkG6Y7BDRERkTOzGMjl2YxEREZFZY8sOERGRMXFRQZNjsENERGRE3BvL9NiNRUREZKbi4uLg6+sLW1tbBAQE4MiRI9XmP3ToEAICAmBra4sWLVpg7dq1anl27tyJNm3aQKlUok2bNti1a5fsfFRUFBQKhezw8PAw6HPVFIMdIiIiYyofoKzvUUM7duzAtGnTMG/ePCQnJyMkJAR9+/ZFamqqxvwpKSno168fQkJCkJycjLlz52LKlCnYuXOnlCcxMRHDhw/H6NGjcf78eYwePRrDhg3DyZMnZWW1bdsWmZmZ0nHhwoUa19+QFEKwbaym8vPz4eTkhG4YBCuFtamrQ0REOioVJUjAbuTl5cHR0dGgZZf/W9G90xxYWdrqVVZpWSEOno2pUT07d+6MTp06Yc2aNVJa69atMXjwYMTExKjlnzVrFr755htcuXJFSouIiMD58+eRmJgIABg+fDjy8/Pxww8/SHn69OkDZ2dnbNu2DcCDlp2vv/4a586d0+VRjYItO0RERHVEfn6+7CgqKtKYr7i4GElJSQgLC5Olh4WF4fjx4xqvSUxMVMvfu3dvnDlzBiUlJdXmqVzmtWvX4OnpCV9fX4wYMQK///57jZ7T0BjsEBERGVH5AGV9DwDw8vKCk5OTdGhqoQGAnJwclJWVwd3dXZbu7u6OrKwsjddkZWVpzF9aWoqcnJxq81Qss3PnztiyZQv27t2LdevWISsrC8HBwcjNza3ZizMgzsYiIiIyJgEDLCr44D9paWmybiylUlntZQqFQl6MEGppD8tfOf1hZfbt21f6uV27dggKCoKfnx82b96MyMjIautrLAx2iIiI6ghHR0etxuy4ubnB0tJSrRUnOztbrWWmnIeHh8b8VlZWcHV1rTZPVWUCgL29Pdq1a4dr1649tN7Gwm4sIiIiYzLBbCwbGxsEBAQgPj5elh4fH4/g4GCN1wQFBanl37dvHwIDA2FtbV1tnqrKBICioiJcuXIFTZs2rdEzGBJbdoiIiIxJBaDqniPty6ihyMhIjB49GoGBgQgKCsLHH3+M1NRUREREAADmzJmD9PR0bNmyBcCDmVerVq1CZGQkJkyYgMTERKxfv16aZQUAU6dORdeuXfHBBx9g0KBB2L17N/bv34+jR49KeWbMmIGBAweiefPmyM7OxqJFi5Cfn48xY8bo9w70wGCHiIjIDA0fPhy5ublYuHAhMjMz4e/vjz179sDb2xsAkJmZKVtzx9fXF3v27MH06dOxevVqeHp6YsWKFRg6dKiUJzg4GNu3b8fbb7+Nd955B35+ftixYwc6d+4s5bl58yZGjhyJnJwcNG7cGM8++yxOnDgh3dcUuM6ODrjODhGReXgU6+z08J8JK8vqBxI/TGlZEQ5cXGKUetYHbNkhIiIyJh1XQFYrg3TGAcpERERk1tiyQ0REZExs2TE5BjtERETGxGDH5OpcN1ZRURE6dOgAhUKhtslYamoqBg4cCHt7e7i5uWHKlCkoLi6W5blw4QJCQ0NhZ2eHxx57DAsXLgTHaBMREZmvOteyM3PmTHh6euL8+fOy9LKyMvTv3x+NGzfG0aNHkZubizFjxkAIgZUrVwJ4MDK+V69e6N69O06fPo1ff/0V4eHhsLe3x1tvvWWKxyEiInNnonV26G91Ktj54YcfsG/fPuzcuVO2vTzwYAXHy5cvIy0tDZ6engCADz/8EOHh4Xj//ffh6OiIzz77DIWFhdi0aROUSiX8/f3x66+/Yvny5YiMjKx2vxAiIiJdVNzIU58ySHd1phvr1q1bmDBhArZu3YoGDRqonU9MTIS/v78U6AAPtp0vKipCUlKSlCc0NFS2cVrv3r2RkZGB69evV3nvoqIi5Ofnyw4iIiKqG+pEsCOEQHh4OCIiIhAYGKgxj6Zt552dnWFjYyNtWlbV1vTl56oSExMDJycn6fDy8tLncYiIqD4xwd5YJGfSYCcqKgoKhaLa48yZM1i5ciXy8/MxZ86casvT1A1Veet5bbavr2zOnDnIy8uTjrS0tJo8JhER1WcqYZiDdGbSMTuTJ0/GiBEjqs3j4+ODRYsW4cSJE7LuJwAIDAzEyy+/jM2bN8PDwwMnT56Unb99+zZKSkqk1puqtqYHUO329EqlUu3eREREVDeYNNhxc3ODm5vbQ/OtWLECixYtkj5nZGSgd+/ess3HgoKC8P777yMzM1PaRn7fvn1QKpUICAiQ8sydOxfFxcWwsbGR8nh6esLHx8fAT0dERASus1ML1IkxO82bN4e/v790PP744wAAPz8/NGvWDAAQFhaGNm3aYPTo0UhOTsaBAwcwY8YMTJgwQdo0bdSoUVAqlQgPD8fFixexa9cuREdHcyYWEREZkSHG6zDY0UedCHa0YWlpie+//x62trbo0qULhg0bhsGDB2PZsmVSHicnJ8THx+PmzZsIDAzExIkTERkZicjISBPWnIiIiIypTq2zU87Hx0fjqsfNmzfHd999V+217dq1w+HDh41VNSIiIjl2Y5lcnQx2iIiI6gyVAbqhOBtLL2bTjUVERESkCVt2iIiIjEmoHhz6lkE6Y7BDRERkTByzY3LsxiIiIiKzxpYdIiIiY+IAZZNjsENERGRM7MYyOXZjERERkVljyw4REZExCRigZccgNam3GOwQEREZE7uxTI7dWERERGTW2LJDRERkTCoVAD0XBVRxUUF9MNghIiIyJnZjmRy7sYiIiMissWWHiIjImNiyY3IMdoiIiIyJKyibHLuxiIiIyKyxZYeIiMiIhFBBCP1mU+l7fX3HYIeIiMiYhNC/G4pjdvTCbiwiIiIya2zZISIiMiZhgAHKbNnRC4MdIiIiY1KpAIWeY244Zkcv7MYiIiIis8aWHSIiImNiN5bJMdghIiIyIqFSQejZjcWp5/phNxYRERGZNbbsEBERGRO7sUyOwQ4REZExqQSgYLBjSuzGIiIiIrPGlh0diP9F2KUo0btlkoiITKcUJQD+/nvdKIQAoO86O/zHRh8MdnRw584dAMBR7DFxTYiIyBDu3LkDJycno5QtVAJCz24sowZj9QCDHR14enoiLS0NDg4OUCgUpq4OACA/Px9eXl5IS0uDo6OjqatTa/E9aY/vSjt8T9qpre9JCIE7d+7A09PT1FUhI2KwowMLCws0a9bM1NXQyNHRsVb9RVJb8T1pj+9KO3xP2qmN78lYLToSoYL+3Vi6XR8XF4elS5ciMzMTbdu2RWxsLEJCQqrMf+jQIURGRuLSpUvw9PTEzJkzERERIcuzc+dOvPPOO/jtt9/g5+eH999/H0OGDNHrvsbGAcpERERGJFTCIEdN7dixA9OmTcO8efOQnJyMkJAQ9O3bF6mpqRrzp6SkoF+/fggJCUFycjLmzp2LKVOmYOfOnVKexMREDB8+HKNHj8b58+cxevRoDBs2DCdPntT5vo+CQrAj0Czk5+fDyckJeXl5te5bU23C96Q9vivt8D1ppz6+p/Jn7qYYAiuFtV5llYoSJIhdNXp/nTt3RqdOnbBmzRoprXXr1hg8eDBiYmLU8s+aNQvffPMNrly5IqVFRETg/PnzSExMBAAMHz4c+fn5+OGHH6Q8ffr0gbOzM7Zt26bTfR8FtuyYCaVSifnz50OpVJq6KrUa35P2+K60w/eknfr8nkpFEUpVeh6iCMCDAKriUVRUpPGexcXFSEpKQlhYmCw9LCwMx48f13hNYmKiWv7evXvjzJkzKCkpqTZPeZm63PdR4JgdM6FUKhEVFWXqatR6fE/a47vSDt+Tdurje7KxsYGHhweOZhlm5m7Dhg3h5eUlS5s/f77G95qTk4OysjK4u7vL0t3d3ZGVlaWx/KysLI35S0tLkZOTg6ZNm1aZp7xMXe77KDDYISIiMgJbW1ukpKSguLjYIOUJIdRmAD+spaxyfk1lPCx/5XRtyqzpfY2NwQ4REZGR2NrawtbW9pHf183NDZaWlmqtKdnZ2WqtLuU8PDw05reysoKrq2u1ecrL1OW+jwLH7BAREZkZGxsbBAQEID4+XpYeHx+P4OBgjdcEBQWp5d+3bx8CAwNhbW1dbZ7yMnW57yMhiIiIyOxs375dWFtbi/Xr14vLly+LadOmCXt7e3H9+nUhhBCzZ88Wo0ePlvL//vvvokGDBmL69Oni8uXLYv369cLa2lp8+eWXUp5jx44JS0tLsXjxYnHlyhWxePFiYWVlJU6cOKH1fU2BwU4dVVhYKJ566ikBQCQnJ8vO3bhxQwwYMEA0aNBAuLq6ijfffFMUFRXJ8vz888+ia9euwtbWVnh6eooFCxYIlUr1CJ/AuFJSUsTYsWOFj4+PsLW1FS1atBDvvvuu2nvgu9Js9erVwsfHRyiVStGpUydx+PBhU1fpkYqOjhaBgYGiYcOGonHjxmLQoEHil19+keVRqVRi/vz5omnTpsLW1laEhoaKixcvyvIUFhaKyZMnC1dXV9GgQQMxcOBAkZaW9igf5ZGKjo4WAMTUqVOlNL4n01q9erXw9vYWNjY2olOnTuLQoUPSuTFjxojQ0FBZ/oSEBNGxY0dhY2MjfHx8xJo1a9TK/M9//iOeeOIJYW1tLZ588kmxc+fOGt3XFBjs1FFTpkwRffv2VQt2SktLhb+/v+jevbs4e/asiI+PF56enmLy5MlSnry8POHu7i5GjBghLly4IHbu3CkcHBzEsmXLTPAkxvHDDz+I8PBwsXfvXvHbb7+J3bt3iyZNmoi33npLysN3pVn5t7J169aJy5cvi6lTpwp7e3tx48YNU1ftkendu7fYuHGjuHjxojh37pzo37+/aN68ubh7966UZ/HixcLBwUHs3LlTXLhwQQwfPlw0bdpU5OfnS3kiIiLEY489JuLj48XZs2dF9+7dxVNPPSVKS0tN8VhGderUKeHj4yPat28vC3b4nqg2YLBTB+3Zs0c8+eST4tKlS2rBzp49e4SFhYVIT0+X0rZt2yaUSqXIy8sTQggRFxcnnJycRGFhoZQnJiZGeHp6mnWLxZIlS4Svr6/0me9Ks2eeeUZERETI0p588kkxe/ZsE9XI9LKzswUA6dupSqUSHh4eYvHixVKewsJC4eTkJNauXSuEEOKvv/4S1tbWYvv27VKe9PR0YWFhIX788cdH+wBGdufOHdGqVSsRHx8vQkNDpWCH74lqCw5QrmNu3bqFCRMmYOvWrWjQoIHa+cTERPj7+8s2tevduzeKioqQlJQk5QkNDZVNWezduzcyMjJw/fp1oz+DqeTl5cHFxUX6zHelrrYuCGZqeXl5ACD9/qSkpCArK0v2npRKJUJDQ6X3lJSUhJKSElkeT09P+Pv7m927nDRpEvr374+ePXvK0vmeqLZgsFOHCCEQHh6OiIgIBAYGasyjacEnZ2dn2NjYSFMBq1oUqvycOfrtt9+wcuVK2YZ2fFfqauuCYKYkhEBkZCSee+45+Pv7A/j7/3117ykrKws2NjZwdnauMo852L59O86ePatxGwC+J6otGOzUAlFRUVAoFNUeZ86cwcqVK5Gfn485c+ZUW56mhZtEpQWdtFk4qjbS9l1VlJGRgT59+uCll17C+PHjZefM+V3po7YtCGZKkydPxs8//yzt+1ORLu/JnN5lWloapk6dik8//bTatWTq+3si0+OigrXA5MmTMWLEiGrz+Pj4YNGiRThx4oTaipmBgYF4+eWXsXnzZnh4eMh2nwWA27dvo6SkRPp2VdWiUID6N7DaRtt3VS4jIwPdu3dHUFAQPv74Y1k+c39XuqitC4KZyptvvolvvvkGhw8fRrNmzaR0Dw8PAA9aJZo2bSqlV3xPHh4eKC4uxu3bt2WtFtnZ2aZdb8SAkpKSkJ2djYCAACmtrKwMhw8fxqpVq3D16lUAfE9UC5horBDp4MaNG+LChQvSsXfvXgFAfPnll9I0zfJBtxkZGdJ127dvVxt026hRI9kU68WLF5vdoNubN2+KVq1aiREjRmic1cF3pdkzzzwj3njjDVla69at69UAZZVKJSZNmiQ8PT3Fr7/+qvG8h4eH+OCDD6S0oqIijQNvd+zYIeXJyMgwq4G3+fn5sr+TLly4IAIDA8Urr7wiLly4wPdEtQaDnTosJSWlyqnnPXr0EGfPnhX79+8XzZo1k02n/uuvv4S7u7sYOXKkuHDhgvjqq6+Eo6OjWU2nTk9PFy1bthT/+Mc/xM2bN0VmZqZ0lOO70qw2Lgj2qL3xxhvCyclJJCQkyH53CgoKpDyLFy8WTk5O4quvvhIXLlwQI0eO1DilulmzZmL//v3i7Nmz4h//+IfZT6muOBtLCL4nqh0Y7NRhmoIdIR60APXv31/Y2dkJFxcXMXnyZNnUaSEeLJQXEhIilEql8PDwEFFRUWbVUrFx40YBQONREd+VZrVtQbBHrarfnY0bN0p5yhfL8/DwEEqlUnTt2lVcuHBBVs79+/fF5MmThYuLi7CzsxMDBgwQqampj/hpHq3KwQ7fE9UGCiH+N9qSiIiIyAxxNhYRERGZNQY7REREZNYY7BAREZFZY7BDREREZo3BDhEREZk1BjtERERk1hjsEBERkVljsENERERmjcEOEUnWr1+PsLAwvcrIzs5G48aNkZ6ebqBaERHphysoExEAoKioCC1atMD27dsREhKiV1mRkZHIz8/HJ598YqDaERHpji07RAQA2LlzJxo2bKh3oAMAr732Gj777DPcvn3bADUjItIPgx0iM/PHH3/Aw8MD0dHRUtrJkydhY2ODffv2VXnd9u3b8fzzz8vSwsPDMXjwYERHR8Pd3R2NGjXCggULUFpaiv/7v/+Di4sLmjVrhg0bNsiua9euHTw8PLBr1y7DPhwRkQ4Y7BCZmcaNG2PDhg2IiorCmTNncPfuXbzyyiuYOHFiteNxjhw5gsDAQLX0n376CRkZGTh8+DCWL1+OqKgoDBgwAM7Ozjh58iQiIiIQERGBtLQ02XXPPPMMjhw5YvDnIyKqKY7ZITJTkyZNwv79+/H000/j/PnzOH36NGxtbTXm/euvv+Ds7IzDhw/LurHCw8ORkJCA33//HRYWD74bPfnkk2jSpAkOHz4MACgrK4OTkxM++eQTjBgxQro2MjISycnJOHjwoBGfkojo4diyQ2Smli1bhtLSUnzxxRf47LPPqgx0AOD+/fsAoDFP27ZtpUAHANzd3dGuXTvps6WlJVxdXZGdnS27zs7ODgUFBfo+BhGR3hjsEJmp33//HRkZGVCpVLhx40a1eV1dXaFQKDQOKLa2tpZ9VigUGtNUKpUs7c8//0Tjxo11rD0RkeEw2CEyQ8XFxXj55ZcxfPhwLFq0COPGjcOtW7eqzG9jY4M2bdrg8uXLBqvDxYsX0bFjR4OVR0SkKwY7RGZo3rx5yMvLw4oVKzBz5ky0bt0a48aNq/aa3r174+jRowa5f0FBAZKSkvReoJCIyBAY7BCZmYSEBMTGxmLr1q1wdHSEhYUFtm7diqNHj2LNmjVVXjdhwgTs2bMHeXl5etdh9+7daN68uUHW7CEi0hdnYxGRZNiwYejYsSPmzJmjVznPPPMMpk2bhlGjRhmoZkREumPLDhFJli5dioYNG+pVRnZ2Nl588UWMHDnSQLUiItIPW3aIiIjIrLFlh4iIiMwagx0iIiIyawx2iIiIyKwx2CEiIiKzxmCHiIiIzBqDHSIiIjJrDHaIiIjIrDHYISIiIrPGYIeIiIjM2v8DzmN3pLRMvjsAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "\n", "# pick the first day with data\n", "da = summaries.f_daily_mean.isel(time=0)\n", "plt.figure(figsize=(6, 5))\n", "im = plt.imshow(da.values, origin=\"lower\",\n", " extent=[float(clim.x.min()), float(clim.x.max()),\n", " float(clim.y.min()), float(clim.y.max())])\n", "plt.colorbar(im, label=\"Normalized footprint\")\n", "plt.title(\"Daily Mean Footprint (first day)\")\n", "plt.xlabel(\"x (m)\"); plt.ylabel(\"y (m)\")\n", "plt.show()\n" ] }, { "cell_type": "markdown", "id": "4bade2e5", "metadata": {}, "source": [ "\n", "## 6) Export 80% Contours to a GeoPackage\n", "\n", "Writes layers like: `daily_mean_r80`, `monthly_etw_r80`, etc. \n", "Contours are generated with a robust alternative to `plt.contour` that can use `skimage` or `rasterio`【8†source】.\n" ] }, { "cell_type": "code", "execution_count": 9, "id": "74a7c10e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "GeoPackage written to: ffp_outputs\\footprints_80pct.gpkg\n" ] } ], "source": [ "\n", "gpkg_path = out_dir / \"footprints_80pct.gpkg\"\n", "gpkg_written = export_contours_gpkg(\n", " clim,\n", " summaries,\n", " df=df,\n", " station_lat=cfg[\"station_latitude\"],\n", " station_lon=cfg[\"station_longitude\"],\n", " gpkg_path=str(gpkg_path),\n", " crs_out=\"auto\", # chooses a suitable UTM\n", " levels=(0.8,), # export the 80% source-area contour\n", " contour_method=\"auto\",\n", ")\n", "print(\"GeoPackage written to:\", gpkg_written)\n" ] }, { "cell_type": "markdown", "id": "7e59fc04", "metadata": {}, "source": [ "\n", "## 7) Export GeoTIFF Rasters\n", "\n", "Each time slice (daily/monthly) is written as a separate `.tif` with correct georeferencing around the tower origin【8†source】.\n" ] }, { "cell_type": "code", "execution_count": 18, "id": "053ea915", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "WindowsPath('ffp_outputs/rasters')" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "tif_dir = out_dir / \"rasters\"\n", "export_rasters_geotiff(\n", " clim,\n", " summaries,\n", " station_lat=cfg[\"station_latitude\"],\n", " station_lon=cfg[\"station_longitude\"],\n", " out_dir=str(tif_dir),\n", " which=(\"daily_mean\", \"monthly_etw\"),\n", " prefix=\"ffp\",\n", ")\n", "tif_dir\n" ] }, { "cell_type": "markdown", "id": "e5d6dd2e", "metadata": {}, "source": [ "\n", "## 8) Export Contour Stats to CSV\n", "\n", "Creates a compact CSV with area (ha) and centroid (lat/lon) for each contour and time slice【8†source】.\n" ] }, { "cell_type": "code", "execution_count": 10, "id": "faa48c12", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Stats CSV saved to: ffp_outputs\\contour_stats.csv\n" ] }, { "data": { "application/vnd.microsoft.datawrangler.viewer.v0+json": { "columns": [ { "name": "index", "rawType": "int64", "type": "integer" }, { "name": "layer", "rawType": "object", "type": "string" }, { "name": "time", "rawType": "object", "type": "string" }, { "name": "r", "rawType": "float64", "type": "float" }, { "name": "area_ha", "rawType": "float64", "type": "float" }, { "name": "centroid_lon", "rawType": "float64", "type": "float" }, { "name": "centroid_lat", "rawType": "float64", "type": "float" } ], "ref": "6105b156-e1b4-47b5-982e-3aa94bf0d52e", "rows": [ [ "0", "daily_mean", "2024-06-24T00:00:00", "0.8", "1.455", "-111.5707397021138", "37.7355272995034" ], [ "1", "daily_mean", "2024-06-25T00:00:00", "0.8", "1.455", "-111.57078934877204", "37.73550857845269" ], [ "2", "daily_mean", "2024-06-26T00:00:00", "0.8", "1.425", "-111.57086471777262", "37.73555173974199" ], [ "3", "daily_mean", "2024-06-27T00:00:00", "0.8", "1.365", "-111.57080246143788", "37.7353904776767" ], [ "4", "daily_mean", "2024-06-28T00:00:00", "0.8", "1.345", "-111.57096371209956", "37.73537987353557" ] ], "shape": { "columns": 6, "rows": 5 } }, "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
layertimerarea_hacentroid_loncentroid_lat
0daily_mean2024-06-24T00:00:000.81.455-111.57074037.735527
1daily_mean2024-06-25T00:00:000.81.455-111.57078937.735509
2daily_mean2024-06-26T00:00:000.81.425-111.57086537.735552
3daily_mean2024-06-27T00:00:000.81.365-111.57080237.735390
4daily_mean2024-06-28T00:00:000.81.345-111.57096437.735380
\n", "
" ], "text/plain": [ " layer time r area_ha centroid_lon centroid_lat\n", "0 daily_mean 2024-06-24T00:00:00 0.8 1.455 -111.570740 37.735527\n", "1 daily_mean 2024-06-25T00:00:00 0.8 1.455 -111.570789 37.735509\n", "2 daily_mean 2024-06-26T00:00:00 0.8 1.425 -111.570865 37.735552\n", "3 daily_mean 2024-06-27T00:00:00 0.8 1.365 -111.570802 37.735390\n", "4 daily_mean 2024-06-28T00:00:00 0.8 1.345 -111.570964 37.735380" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "csv_path = out_dir / \"contour_stats.csv\"\n", "export_contour_stats_csv(\n", " df,\n", " clim,\n", " summaries,\n", " station_lat=cfg[\"station_latitude\"],\n", " station_lon=cfg[\"station_longitude\"],\n", " csv_path=str(csv_path),\n", " levels=(0.8,),\n", ")\n", "print(\"Stats CSV saved to:\", csv_path)\n", "pd.read_csv(csv_path).head()\n" ] }, { "cell_type": "markdown", "id": "18f51766", "metadata": {}, "source": [ "\n", "## Tips & Troubleshooting\n", "\n", "- If you see missing column errors, verify your CSV has the expected fields or update the INI to map the correct names. The helper expects AMF-like columns (e.g., `WD`, `WS`, `USTAR`, `MO_LENGTH`, `V_SIGMA`) and renames them internally【8†source】.\n", "- ET weighting converts LE (W/m²) to mm/hr using `LE / 680.6`【8†source】.\n", "- For exports, ensure `geopandas`, `shapely`, `pyproj`, and `rasterio` are installed.\n", "- To change source-area levels, pass `levels=(0.5, 0.8)` to the export functions.\n", "- To use a fixed CRS (instead of UTM auto), pass `crs_out=EPSG_CODE`.\n" ] } ], "metadata": { "kernelspec": { "display_name": "py313", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.1" } }, "nbformat": 4, "nbformat_minor": 5 }