From 025cff03f8304cbe55cdbef3879312cc5950bc91 Mon Sep 17 00:00:00 2001 From: doc78 Date: Wed, 1 Jul 2026 15:10:21 +0000 Subject: [PATCH 01/36] Update in setup test instruction --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index eb672278..ba2c8c77 100755 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ IMPORTANT Note: To test pip installation: python setup.py testpypi -pip install --index-url https://test.pypi.org/simple/ lisflood-model==5.0.0 +pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple lisflood-model==5.0.0 To publish on PyPi: From c7f0416dbbe2b14c813c91c21314ed9bf0c5d0b2 Mon Sep 17 00:00:00 2001 From: doc78 Date: Thu, 2 Jul 2026 14:49:13 +0000 Subject: [PATCH 02/36] Added zenodo badge. Small update to reference xml --- README.md | 2 ++ src/lisfloodSettings_reference.xml | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/README.md b/README.md index a8e9f3d4..538db81f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![DOI](https://img.shields.io/badge/DOI-10.5281%2Fzenodo.21107672-blue.svg)](https://doi.org/10.5281/zenodo.21107672) + # Lisflood OS This repository hosts source code of LISFLOOD model. diff --git a/src/lisfloodSettings_reference.xml b/src/lisfloodSettings_reference.xml index 57097349..2c7c7832 100644 --- a/src/lisfloodSettings_reference.xml +++ b/src/lisfloodSettings_reference.xml @@ -47,6 +47,7 @@ You can use builtin path variables in this template and reference to other paths + @@ -1723,6 +1724,13 @@ You can use builtin path variables in this template and reference to other paths + + + location of calibration points + OPTIONAL: nominal map with locations of calibration points + + + OPTIONAL: observed or simulated input hydrographs as time series [cu m / s] @@ -5651,6 +5659,13 @@ You can use builtin path variables in this template and reference to other paths + + + location of calibration points + OPTIONAL: nominal map with locations of calibration points + + + Observed or simulated input hydrographs as From 657726f13677afbb67d11256269ee542dbccfa21 Mon Sep 17 00:00:00 2001 From: doc78 Date: Thu, 2 Jul 2026 14:57:36 +0000 Subject: [PATCH 03/36] Updated maintainer list in docker file --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 92ad8fb4..eac44765 100755 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ # docker push jrce1/lisflood FROM continuumio/miniconda3 -LABEL maintainer="Stefania Grimaldi, Cinzia Mazzetti, Carlo Russo, Valerio Lorini, Ad de Roo" +LABEL maintainer="Stefania Grimaldi, Timo Schaffhauser, Carlo Russo, Cinzia Mazzetti, Corentin Carton De Wiart" ENV DEBIAN_FRONTEND=noninteractive From 9936a0fadaa3652c08500b9dfa8e71439e84ce3e Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Wed, 8 Jul 2026 17:42:04 +0200 Subject: [PATCH 04/36] introducing packing with dummy values --- .gitignore | 3 + docs/5_annex_output-files/index.md | 2 +- packing_replacements.md | 126 +++++++++++ packing_scale_offset_values.md | 83 ++++++++ .../global_modules/default_options.py | 198 ++++++++++-------- src/lisflood/global_modules/netcdf.py | 25 ++- src/lisflood/global_modules/output.py | 28 ++- src/lisfloodSettings_reference.xml | 12 ++ 8 files changed, 377 insertions(+), 100 deletions(-) create mode 100644 packing_replacements.md create mode 100644 packing_scale_offset_values.md diff --git a/.gitignore b/.gitignore index ef5f354a..252b2998 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ lisflood_model.egg-info .vscode/ *.ipynb .ipynb_checkpoints/ +implementation_guide_scale_offset_packing.md +lisflood_optimization_report.md +lisflood_optimization_report_v2.md diff --git a/docs/5_annex_output-files/index.md b/docs/5_annex_output-files/index.md index a03575f9..a1ef8598 100644 --- a/docs/5_annex_output-files/index.md +++ b/docs/5_annex_output-files/index.md @@ -157,7 +157,7 @@ To speed up the pre-run and to prevent that results are taken from the pre-run, | actual transpiration | repTaMaps | $\frac{mm}{timestep}$ | TaMaps | tact | | rainfall interception | repInterceptionMaps | $\frac{mm}{timestep}$ | InterceptionMaps
InterceptionForestMaps | int
intF | | evaporation of intercepted water | repEWIntMaps | $\frac{mm}{timestep}$ | EWIntMaps | ewint | -| leaf drainage | repLeafDrainageMaps | $\frac{mm}{timestep}$ | LeafDrainageMaps
LeafDrainageForestMaps | ldra
draF | +| leaf drainage | repLeafDrainageMaps | $\frac{mm}{timestep}$ | LeafDrainageMaps
LeafDrainageForestMaps no | ldra
draF | | infiltration | repInfiltrationMaps | $\frac{mm}{timestep}$ | InfiltrationMaps
InfiltrationForestMaps | inf
infF | | preferential (bypass) flow | repPrefFlowMaps | $\frac{mm}{timestep}$ | PrefFlowMaps
PrefFlowtherMaps
PrefFlowForestMaps
PrefFlowIrrigationMaps | pflowpixel
pflow
pflowF
pflowi | | percolation upper to lower soil layer | repPercolationMaps | $\frac{mm}{timestep}$ | Percolation1ato1bOtherMaps
Percolation1to1bForestMaps
Percolation1ato1bIrrigationMaps
Percolation1bto2OtherMaps
Percolation1bto2ForestMaps
Percolation1bto2IrrigationMaps | Percolation1ato1bOther
Percolation1ato1bForest
Percolation1to2Irrigation
Percolation1bto2Other
Percolation1bto2Forest
Percolation1bto2Irrigation | diff --git a/packing_replacements.md b/packing_replacements.md new file mode 100644 index 00000000..c517bccb --- /dev/null +++ b/packing_replacements.md @@ -0,0 +1,126 @@ +# Find-and-Replace Guide: scale_factor / add_offset Values + +Replace `scale_factor=1, add_offset=0` with the correct values below. +Use your editor's find-and-replace on each variable name to locate it. + +**Important:** For State/End entries, REMOVE scale_factor and add_offset entirely +(let them default to None). They should never be packed. + +--- + +## Variables to REMOVE packing from (State/End maps — set to None) + +These have `scale_factor=1, add_offset=0` but should NOT be packed. +Remove the `, scale_factor=1, add_offset=0` from these entries entirely: + +- SnowCoverAEnd, SnowCoverAState +- SnowCoverBEnd, SnowCoverBState +- SnowCoverCEnd, SnowCoverCState +- Theta1End, Theta1State, Theta1ForestState, Theta1IrrigationState +- Theta2ForestState, Theta2IrrigationState, Theta2State +- Theta3ForestState, Theta3IrrigationState, Theta3State +- UZForestState, UZIrrigationState, UZState +- WaterDepthState +- SeepTopToSubBAverageOtherMap (end=['InitLisflood'] — this is a prerun end map) +- SeepTopToSubBAverageForestMap (end=['InitLisflood']) +- SeepTopToSubBAverageIrrigationMap (end=['InitLisflood']) + +--- + +## Variables to UPDATE with proper values + +Format: `VariableName` → `scale_factor=X, add_offset=Y` +Design range and precision shown for reference. + +### Discharge (m3/s) — range 0 to 400,000 +- `DischargeMaps` → `scale_factor=6.104, add_offset=200000.0` + +### Direct Runoff (mm) — range 0 to 400 +- `DirectRunoffMaps` → `scale_factor=0.006104, add_offset=200.0` + +### Evaporation (mm/day) — range 0 to 20 +- `ESActMaps` → `scale_factor=3.052e-4, add_offset=10.0` +- `ESRefMapsOut` → `scale_factor=3.052e-4, add_offset=10.0` + +### ET (mm/day) — range -10 to 1000 +- `ETActMaps` → `scale_factor=0.01541, add_offset=495.0` +- `ETActBudykoMaps` → `scale_factor=0.01541, add_offset=495.0` +- `ETRefMapsOut` → `scale_factor=3.052e-4, add_offset=10.0` + +### Interception/Transpiration (mm/day) — range 0 to 15 +- `EWIntForestMaps` → `scale_factor=2.289e-4, add_offset=7.5` +- `EWIntMaps` → `scale_factor=2.289e-4, add_offset=7.5` +- `EWRefMapsOut` → `scale_factor=3.052e-4, add_offset=10.0` +- `EWater` → `scale_factor=3.052e-4, add_offset=10.0` +- `InterceptionForestMaps` → `scale_factor=2.289e-4, add_offset=7.5` +- `InterceptionMaps` → `scale_factor=2.289e-4, add_offset=7.5` + +### Fast Runoff / Preferential Flow (mm) — range 0 to 400 +- `FastRunoffMaps` → `scale_factor=0.006104, add_offset=200.0` + +### GW Percolation UZ to LZ (mm) — range 0 to 3 +- `GwPercUZLZForestMaps` → `scale_factor=4.578e-5, add_offset=1.5` +- `GwPercUZLZIrrigationMaps` → `scale_factor=4.578e-5, add_offset=1.5` +- `GwPercUZLZOtherMaps` → `scale_factor=4.578e-5, add_offset=1.5` +- `GwPercUZLZMaps` → `scale_factor=4.578e-5, add_offset=1.5` + +### Infiltration (mm) — range 0 to 500 +- `InfiltrationForestMaps` → `scale_factor=0.007630, add_offset=250.0` +- `InfiltrationMaps` → `scale_factor=0.007630, add_offset=250.0` + +### Seep to GW (mm) — range 0 to 60 +- `SeepSubToGWMaps` → `scale_factor=9.156e-4, add_offset=30.0` + +### Snow (mm) — range 0 to 200 +- `SnowMaps` → `scale_factor=0.003052, add_offset=100.0` + +### Snow Cover (mm) — range 0 to 10000 +- `SnowCoverMaps` → `scale_factor=0.15260, add_offset=5000.0` + +### Snow Melt (mm) — range 0 to 250 +- `SnowMeltMaps` → `scale_factor=0.003815, add_offset=125.0` + +### Surface Runoff (mm) — range 0 to 500 +- `SurfaceRunoffMaps` → `scale_factor=0.007630, add_offset=250.0` + +### Transpiration (mm/day) — range -10 to 15 +- `TaOtherMaps` → `scale_factor=3.815e-4, add_offset=2.5` +- `TaForestMaps` → `scale_factor=3.815e-4, add_offset=2.5` +- `TaIrrigationMaps` → `scale_factor=3.815e-4, add_offset=2.5` +- `TaMaps` → `scale_factor=3.815e-4, add_offset=2.5` + +### Theta (soil moisture fraction) — range 0 to 1 +- `Theta1Maps` → `scale_factor=1.526e-5, add_offset=0.5` +- `Theta1ForestMaps` → `scale_factor=1.526e-5, add_offset=0.5` +- `Theta1IrrigationMaps` → `scale_factor=1.526e-5, add_offset=0.5` +- `Theta2Maps` → `scale_factor=1.526e-5, add_offset=0.5` +- `Theta2ForestMaps` → `scale_factor=1.526e-5, add_offset=0.5` +- `Theta2IrrigationMaps` → `scale_factor=1.526e-5, add_offset=0.5` +- `Theta3Maps` → `scale_factor=1.526e-5, add_offset=0.5` +- `Theta3ForestMaps` → `scale_factor=1.526e-5, add_offset=0.5` +- `Theta3IrrigationMaps` → `scale_factor=1.526e-5, add_offset=0.5` + +### Total Runoff (mm) — range 0 to 500 +- `TotalRunoffMaps` → `scale_factor=0.007630, add_offset=250.0` +- `TotalToChanMaps` → `scale_factor=0.007630, add_offset=250.0` + +### Transmission Loss (mm) — range 0 to 600 +- `TransLossMaps` → `scale_factor=0.009156, add_offset=300.0` + +### UZ (mm) — range 0 to 3500 +- `UZForestMaps` → `scale_factor=0.05341, add_offset=1750.0` +- `UZIrrigationMaps` → `scale_factor=0.05341, add_offset=1750.0` +- `UZMaps` → `scale_factor=0.05341, add_offset=1750.0` + +### UZ Outflow (mm) — range 0 to 300 +- `UZOutflowForestMaps` → `scale_factor=0.004578, add_offset=150.0` +- `UZOutflowIrrigationMaps` → `scale_factor=0.004578, add_offset=150.0` +- `UZOutflowOtherMaps` → `scale_factor=0.004578, add_offset=150.0` +- `UZOutflowMaps` → `scale_factor=0.004578, add_offset=150.0` + +### Water Depth (mm) — range 0 to 250 +- `WaterDepthMaps` → `scale_factor=0.003815, add_offset=125.0` + +### Total Water Storage (mm) — range -5000 to 35,000,000 +- `TotalWaterStorageMaps` → **DO NOT PACK** (range too large for int16). Remove scale_factor/add_offset. + diff --git a/packing_scale_offset_values.md b/packing_scale_offset_values.md new file mode 100644 index 00000000..86f49f42 --- /dev/null +++ b/packing_scale_offset_values.md @@ -0,0 +1,83 @@ +# Scale/Offset Packing Values for LISFLOOD Output Variables + +Based on actual GloFAS global run min/max values, with ~20-50% headroom above observed max. + +Formula: `scale_factor = (vmax - vmin) / 65534`, `add_offset = vmin + scale_factor * 32767` + +Only time-series outputs (Maps/All) are listed. State/End maps should NOT be packed. + +| Variable | Unit | Obs Min | Obs Max | Design Min | Design Max | scale_factor | add_offset | Precision (±) | +|----------|------|---------|---------|------------|------------|--------------|------------|---------------| +| dis (DischargeMaps) | m3/s | 0 | 2.93e5 | 0 | 400000 | 6.1040 | 200000.0 | ±3.05 m3/s | +| chanq | m3/s | 0 | 2.93e5 | 0 | 400000 | 6.1040 | 200000.0 | ±3.05 m3/s | +| chanqavgdt | m3/s | 0 | 2.93e5 | 0 | 400000 | 6.1040 | 200000.0 | ±3.05 m3/s | +| chcro (CrossSectionArea) | m2 | 0 | 9.89e7 | 0 | 1.5e8 | 2288.4 | 75000000.0 | ±1144 m2 | +| tws (TotalWaterStorage) | mm | -2396 | 2.69e7 | -5000 | 3.5e7 | 534.4 | 17497500.0 | ±267 mm | +| lz (LowerZone) | mm | -2886 | 1415 | -4000 | 2000 | 0.09156 | -1000.0 | ±0.046 mm | +| uz, uzf, uzi | mm | 0 | 2486 | 0 | 3500 | 0.05341 | 1750.0 | ±0.027 mm | +| scov (SnowCover) | mm | 0 | 5359 | 0 | 8000 | 0.12207 | 4000.0 | ±0.061 mm | +| scova, scovb, scovc | mm | 0 | 6819 | 0 | 10000 | 0.15260 | 5000.0 | ±0.076 mm | +| rain | mm/day | 0 | 509 | 0 | 700 | 0.01068 | 350.0 | ±0.005 mm | +| snow | mm/day | 0 | 132 | 0 | 200 | 0.003052 | 100.0 | ±0.0015 mm | +| smelt (SnowMelt) | mm/day | 0 | 167 | 0 | 250 | 0.003815 | 125.0 | ±0.0019 mm | +| etact (ETactual) | mm/day | -6.3 | 828 | -10 | 1000 | 0.01541 | 495.0 | ±0.0077 mm | +| tact, tactF | mm/day | -6.4 | 7.7 | -10 | 15 | 3.815e-4 | 2.5 | ±0.00019 mm | +| Ta_other | mm/day | 0 | 7.4 | 0 | 15 | 2.289e-4 | 7.5 | ±0.00011 mm | +| esact, esactF | mm/day | 0 | 11.4 | 0 | 20 | 3.052e-4 | 10.0 | ±0.00015 mm | +| dirrun (DirectRunoff) | mm | 0 | 255 | 0 | 400 | 0.006104 | 200.0 | ±0.003 mm | +| srun (SurfaceRunoff) | mm | 0 | 330 | 0 | 500 | 0.007630 | 250.0 | ±0.0038 mm | +| trun (TotalRunoff) | mm | 0 | 331 | 0 | 500 | 0.007630 | 250.0 | ±0.0038 mm | +| inf, infF (Infiltration) | mm | 0 | 314 | 0 | 500 | 0.007630 | 250.0 | ±0.0038 mm | +| pflow, pflowF, pflowO, pflowi | mm | 0 | 293 | 0 | 400 | 0.006104 | 200.0 | ±0.003 mm | +| quz, quzF, quzI, quzO | mm | 0 | 209 | 0 | 300 | 0.004578 | 150.0 | ±0.0023 mm | +| qlz | mm | 0 | 2.0 | 0 | 3 | 4.578e-5 | 1.5 | ±2.3e-5 mm | +| uz2lz, uz2lzF | mm | 0 | 2.0 | 0 | 3 | 4.578e-5 | 1.5 | ±2.3e-5 mm | +| gwloss | mm | 0 | 1.0 | 0 | 2 | 3.052e-5 | 1.0 | ±1.5e-5 mm | +| sgwF, sgwIrrigation, sgwOther, sgwPixel | mm | 0 | 40 | 0 | 60 | 9.156e-4 | 30.0 | ±4.6e-4 mm | +| frost (FrostIndex) | - | 0 | 57 | 0 | 100 | 0.001526 | 50.0 | ±7.6e-4 | +| dslr, dslrf, dslri | days | 1 | 2558 | 0 | 4000 | 0.06104 | 2000.0 | ±0.031 days | +| cseal (CumInterSealed) | mm | 0 | 1.0 | 0 | 1.5 | 2.289e-5 | 0.75 | ±1.1e-5 mm | +| tha, thb, thc, thfa-thic (theta) | - | 0.04 | 0.70 | 0 | 1.0 | 1.526e-5 | 0.5 | ±7.6e-6 | +| ofdir (OFDirectM3) | m3 | 0 | 1.76e6 | 0 | 2.5e6 | 38.15 | 1250000.0 | ±19 m3 | +| offor (OFForestM3) | m3 | 0 | 5.08e6 | 0 | 7.0e6 | 106.8 | 3500000.0 | ±53 m3 | +| ofoth (OFOtherM3) | m3 | 0 | 2.90e6 | 0 | 4.0e6 | 61.04 | 2000000.0 | ±31 m3 | +| wdept (WaterDepth) | mm | 0 | 168 | 0 | 250 | 0.003815 | 125.0 | ±0.0019 mm | +| transloss | mm | 0 | 412 | 0 | 600 | 0.009156 | 300.0 | ±0.0046 mm | +| ttoc (ToChanRunoff) | mm | 0 | 235 | 0 | 350 | 0.005341 | 175.0 | ±0.0027 mm | +| lakeh | m | 0 | 39.5 | 0 | 60 | 9.156e-4 | 30.0 | ±4.6e-4 m | +| lakeprevinq, lakeprevoutq | m3/s | 0 | 1.06e5 | 0 | 150000 | 2.289 | 75000.0 | ±1.14 m3/s | +| rsfil (ReservoirFill) | - | 0 | 0.98 | 0 | 1.5 | 2.289e-5 | 0.75 | ±1.1e-5 | + + +## Notes + +### Design range choices +- Headroom of 20-50% above observed max to accommodate extreme events not seen in the calibration run +- For variables with observed min = 0, design min is kept at 0 (physical lower bound) +- For lz (can go negative due to abstractions), design min set to -4000 based on observed -2886 +- For tws (huge dynamic range 0 to 27M): precision is coarse (±267 mm) — consider whether this variable really needs map output or if TSS at gauges suffices + +### Variables NOT recommended for packing +- `tws` (TotalWaterStorage): extreme dynamic range makes int16 precision poor. Use float32 instead. +- `chcro` (CrossSectionArea): same issue — range 0 to 1.5e8 gives ±1144 m2 precision +- All `.end` and `State` variables: used for warm start, need full precision + +### How to use these values in `default_options.py` + +```python +'DischargeMaps': ReportedMap(name='DischargeMaps', output_var='ChanQAvg', + unit='m3/s', end=[], steps=[], + all=['repDischargeMaps'], restrictoption=[], + monthly=False, yearly=False, + scale_factor=6.1040, add_offset=200000.0), +``` + +### Verification +After implementation, verify with: +```python +# For discharge: design range 0-400000 +# packed = round((value - 200000) / 6.1040) +# At value=0: packed = -32767 ✓ (min int16 usable) +# At value=400000: packed = +32767 ✓ (max int16 usable) +# At value=200000: packed = 0 ✓ (midpoint) +``` diff --git a/src/lisflood/global_modules/default_options.py b/src/lisflood/global_modules/default_options.py index 32de212c..1add2a17 100644 --- a/src/lisflood/global_modules/default_options.py +++ b/src/lisflood/global_modules/default_options.py @@ -1,7 +1,8 @@ from collections import namedtuple TimeSeries = namedtuple('TimeSeries', 'name, output_var, where, repoption, restrictoption, operation') -ReportedMap = namedtuple('ReportedMap', 'name, output_var, unit, end, steps, all, restrictoption, monthly, yearly') +ReportedMap = namedtuple('ReportedMap', 'name, output_var, unit, end, steps, all, restrictoption, monthly, yearly, scale_factor, add_offset') +ReportedMap.__new__.__defaults__ = (None, None) # sets scale and offset per default to None and as optionally default_options = {'EnKF': False, 'InitLisflood': False, @@ -351,7 +352,7 @@ output_var='DirectRunoff', unit='mm', end=[], steps=['repSurfaceRunoffMaps'], all=[''], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=0.006104, add_offset=200.0), 'DischargeEnd': ReportedMap(name='DischargeEnd', output_var='ChanQAvg', unit='m3/s', end=[], steps=[], all=[], restrictoption=[], monthly=False, @@ -359,7 +360,8 @@ 'DischargeMaps': ReportedMap(name='DischargeMaps', output_var='ChanQAvg', unit='m3/s', end=[], steps=[], all=['repDischargeMaps'], restrictoption=[], - monthly=False, yearly=False), + monthly=False, yearly=False, + scale_factor=6.104, add_offset=200000.0), 'EFlowIndicator': ReportedMap(name='EFlowIndicator', output_var='EFlowIndicator', unit='-', end=[], steps=['repTotalAbs'], all=[], restrictoption=['nonInit', 'wateruse', @@ -371,35 +373,43 @@ monthly=False, yearly=False), 'ESActMaps': ReportedMap(name='ESActMaps', output_var='ESActPixel', unit='mm', end=[], steps=[], all=['repESActMaps','repE2O1'], - restrictoption=['nonInit'], monthly=False, yearly=False), + restrictoption=['nonInit'], monthly=False, yearly=False, + scale_factor=1, add_offset=0), 'ESRefMapsOut': ReportedMap(name='ESRefMapsOut', output_var='ESRef', unit='mm', end=[], steps=[], all=['repESRefMaps'], - restrictoption=[], monthly=False, yearly=False), + restrictoption=[], monthly=False, yearly=False, + scale_factor=1, add_offset=0), 'ETActMaps': ReportedMap(name='ETActMaps', output_var='ESActPixel+self.var.TaPixel+self.var.TaInterceptionAll+self.var.EvaAddM3*self.var.M3toMM', unit='mm', end=[], steps=[], all=['repETActMaps','repE2O1'], - restrictoption=['nonInit'], monthly=False, yearly=False), + restrictoption=['nonInit'], monthly=False, yearly=False, + scale_factor=1, add_offset=0), 'ETActBudykoMaps': ReportedMap(name='ETActBudykoMaps', output_var='ESActNoIrrPixel+self.var.TaNoIrrPixel+self.var.TaInterceptionNoIrrPixel', unit='mm', end=[], steps=[], all=['repETActMaps','repE2O1'], - restrictoption=['nonInit'], monthly=False, yearly=False), + restrictoption=['nonInit'], monthly=False, yearly=False, + scale_factor=1, add_offset=0), 'ETRefMapsOut': ReportedMap(name='ETRefMapsOut', output_var='ETRef', unit='mm', end=[], steps=[], all=['repETRefMaps'], - restrictoption=[], monthly=False, yearly=False), + restrictoption=[], monthly=False, yearly=False, + scale_factor=1, add_offset=0), 'EWIntForestMaps': ReportedMap(name='EWIntForestMaps', output_var='TaInterception[1]', unit='mm', end=[], steps=[], all=['repEWIntMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'EWIntMaps': ReportedMap(name='EWIntMaps', output_var='TaInterceptionAll', unit='mm', end=[], steps=[], all=['repEWIntMaps','repE2O1'], - restrictoption=['nonInit'], monthly=False, yearly=False), + restrictoption=['nonInit'], monthly=False, yearly=False, + scale_factor=1, add_offset=0), 'EWRefMapsOut': ReportedMap(name='EWRefMapsOut', output_var='EWRef', unit='mm', end=[], steps=[], all=['repEWRefMaps'], - restrictoption=[], monthly=False, yearly=False), + restrictoption=[], monthly=False, yearly=False, + scale_factor=1, add_offset=0), 'EWater': ReportedMap(name='EWater', output_var='EvaAddM3*self.var.M3toMM', unit='mm', end=[], steps=[], all=['repE2O1'], - restrictoption=['nonInit'], monthly=False, yearly=False), + restrictoption=['nonInit'], monthly=False, yearly=False, + scale_factor=1, add_offset=0), 'FalkenmarkM3Capita1': ReportedMap(name='FalkenmarkM3Capita1', output_var='FalkenmarkM3Capita1', unit='M3Capita', end=[], @@ -426,7 +436,7 @@ output_var='SurfaceRunoff+self.var.UZOutflowPixel', unit='mm', end=[], steps=[], all=['repFastRunoffMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'FossilGroundwaterUsedM3': ReportedMap(name='FossilGroundwaterUsedM3', output_var='FossilGroundwaterUsedM3', unit='m3', end=[], @@ -460,49 +470,49 @@ end=[], steps=['repGwPercUZLZMaps'], all=['repGwPercUZLZMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'GwPercUZLZIrrigationMaps': ReportedMap(name='GwPercUZLZForestMaps', output_var='GwPercUZLZ[2]', unit='mm', end=[], steps=['repGwPercUZLZMaps'], all=['repGwPercUZLZMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'GwPercUZLZOtherMaps': ReportedMap(name='GwPercUZLZForestMaps', output_var='GwPercUZLZ[0]', unit='mm', end=[], steps=[], all=['repGwPercUZLZMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'GwPercUZLZMaps': ReportedMap(name='GwPercUZLZMaps', output_var='GwPercUZLZPixel', unit='mm', end=[], steps=[], all=['repGwPercUZLZMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'InfiltrationForestMaps': ReportedMap(name='InfiltrationForestMaps', output_var='Infiltration[1]', unit='mm', end=[], steps=[], all=['repInfiltrationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'InfiltrationMaps': ReportedMap(name='InfiltrationMaps', output_var='Infiltration[0]', unit='mm', end=[], steps=[], all=['repInfiltrationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'InterceptionForestMaps': ReportedMap(name='InterceptionForestMaps', output_var='Interception[1]', unit='mm', end=[], steps=[], all=['repInterceptionMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'InterceptionMaps': ReportedMap(name='InterceptionMaps', output_var='Interception[0]', unit='mm', end=[], steps=[], all=['repInterceptionMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'LocalFreshwaterM3': ReportedMap(name='LocalFreshwaterM3', output_var='LocalFreshwaterM3', unit='m3', end=[], @@ -535,10 +545,11 @@ output_var='LZOutflowToChannelPixel', unit='mm', end=[], steps=[], all=['repLZOutflowMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'LZState': ReportedMap(name='LZState', output_var='LZ', unit='mm', end=[], steps=['repStateMaps'], all=[], - restrictoption=['nonInit'], monthly=False, yearly=False), + restrictoption=['nonInit'], monthly=False, yearly=False, + scale_factor=1, add_offset=0), 'LakeAbstractionM3': ReportedMap(name='LakeAbstractionM3', output_var='LakeAbstractionM3', unit='m3', end=[], steps=['repTotalAbs'], all=[], @@ -599,15 +610,15 @@ 'MonthETactMM': ReportedMap(name='MonthETactMM', output_var='MonthETactMM', unit='mm', end=[], steps=['repWIndex'], all=[], restrictoption=['nonInit', 'wateruse', 'indicator'], - monthly=False, yearly=False), + monthly=False, yearly=False, scale_factor=1, add_offset=0), 'MonthETdifMM': ReportedMap(name='MonthETdifMM', output_var='MonthETdifMM', unit='mm', end=[], steps=['repWIndex'], all=[], restrictoption=['nonInit', 'wateruse', 'indicator'], - monthly=False, yearly=False), + monthly=False, yearly=False, scale_factor=1, add_offset=0), 'MonthETpotMM': ReportedMap(name='MonthETpotMM', output_var='MonthETpotMM', unit='mm', end=[], steps=['repWIndex'], all=[], restrictoption=['nonInit', 'wateruse', 'indicator'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'TimeSinceStartPrerunChunkEnd': ReportedMap(name='TimeSinceStartPrerunChunkEnd', output_var='TimeSinceStartPrerunChunk', unit='number of steps', end=['InitLisflood'], @@ -697,34 +708,34 @@ output_var='SeepTopToSubA[0]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Percolation1ato1bForestMaps': ReportedMap(name='Percolation1ato1bForestMaps', output_var='SeepTopToSubA[1]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Percolation1ato1bIrrigationMaps': ReportedMap(name='Percolation1ato1bIrrigationMaps', output_var='SeepTopToSubA[2]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Percolation1bto2OtherMaps': ReportedMap(name='Percolation1bto2OtherMaps', output_var='SeepTopToSubB[0]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Percolation1bto2ForestMaps': ReportedMap(name='Percolation1bto2ForestMaps', output_var='SeepTopToSubB[1]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Percolation1bto2IrrigationMaps': ReportedMap(name='Percolation1bto2IrrigationMaps', output_var='SeepTopToSubB[2]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'PrevCmMCTEnd': ReportedMap(name='PrevCmMCTEnd', output_var='PrevCm0', unit='-', end=['repEndMaps'], steps=[], all=[], restrictoption=['nonInit','MCTRouting'], monthly=False, yearly=False), @@ -759,7 +770,7 @@ unit='mm/timestep', end=[], steps=[], all=['repPrecipitationMaps'], restrictoption=[], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'PrefFlowOtherMaps': ReportedMap(name='PrefFlowOtherMaps', output_var='PrefFlow[0]', unit='mm', end=[], steps=[], all=['repPrefFlowMaps'], @@ -781,7 +792,8 @@ yearly=False), 'RainMaps': ReportedMap(name='RainMaps', output_var='Rain', unit='mm', end=[], steps=[], all=['repRainMaps','repE2O1'], - restrictoption=['nonInit'], monthly=False, yearly=False), + restrictoption=['nonInit'], monthly=False, yearly=False, + scale_factor=1, add_offset=0), 'RegionMonthExternalInflowM3': ReportedMap(name='RegionMonthExternalInflowM3', output_var='RegionMonthExternalInflowM3', unit='M3', end=[], @@ -879,115 +891,116 @@ unit='days', end=[], steps=[], all=['repStressDays'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SMStressMap': ReportedMap(name='SMStressMap', output_var='SoilMoistureStressDays[0]', unit='days', end=[], steps=[], all=['repStressDays'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SeepSubToGWotherMaps': ReportedMap(name='SeepSubToGWOtherMaps', output_var='SeepSubToGW[0]', unit='mm', end=[], steps=[], all=['repSeepSubToGWMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SeepSubToGWforestMaps': ReportedMap(name='SeepSubToGWForestMaps', output_var='SeepSubToGW[1]', unit='mm', end=[], steps=[], all=['repSeepSubToGWMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SeepSubToGWirrigationMaps': ReportedMap(name='SeepSubToGWIrrigationMaps', output_var='SeepSubToGW[2]', unit='mm', end=[], steps=[], all=['repSeepSubToGWMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SeepSubToGWMaps': ReportedMap(name='SeepSubToGWMaps', output_var='SeepSubToGWPixel', unit='mm', end=[], steps=[], all=['repSeepSubToGWMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SeepTopToSubBAverageOtherMap': ReportedMap(name='SeepTopToSubBAverageOtherMap', output_var='SeepTopToSubBAv[0]', unit='mm/timestep', end=['InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SeepTopToSubBAverageForestMap': ReportedMap(name='SeepTopToSubBAverageForestMap', output_var='SeepTopToSubBAv[1]', unit='mm/timestep', end=['InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SeepTopToSubBAverageIrrigationMap': ReportedMap(name='SeepTopToSubBAverageIrrigationMap', output_var='SeepTopToSubBAv[2]', unit='mm/timestep', end=['InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SnowCoverAEnd': ReportedMap(name='SnowCoverAEnd', output_var='SnowCoverS[0]', unit='mm', end=['repEndMaps'], steps=[], all=[], restrictoption=[], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SnowCoverAState': ReportedMap(name='SnowCoverAState', output_var='SnowCoverS[0]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SnowCoverBEnd': ReportedMap(name='SnowCoverBEnd', output_var='SnowCoverS[1]', unit='mm', end=['repEndMaps'], steps=[], all=[], restrictoption=[], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SnowCoverBState': ReportedMap(name='SnowCoverBState', output_var='SnowCoverS[1]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SnowCoverCEnd': ReportedMap(name='SnowCoverCEnd', output_var='SnowCoverS[2]', unit='mm', end=['repEndMaps'], steps=[], all=[], restrictoption=[], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SnowCoverCState': ReportedMap(name='SnowCoverCState', output_var='SnowCoverS[2]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SnowCoverMaps': ReportedMap(name='SnowCoverMaps', output_var='SnowCover', unit='mm', end=[], steps=[], all=['repSnowCoverMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SnowMaps': ReportedMap(name='SnowMaps', output_var='Snow', unit='mm', end=[], steps=[], all=['repSnowMaps'], - restrictoption=['nonInit'], monthly=False, yearly=False), + restrictoption=['nonInit'], monthly=False, yearly=False, + scale_factor=1, add_offset=0), 'SnowMeltMaps': ReportedMap(name='SnowMeltMaps', output_var='SnowMelt', unit='mm', end=[], steps=[], all=['repSnowMeltMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'SurfaceRunoffMaps': ReportedMap(name='SurfaceRunoffMaps', output_var='SurfaceRunoff', unit='mm', end=[], steps=[], all=['repSurfaceRunoffMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'TaOtherMaps': ReportedMap(name='TaOtherMaps', output_var='Ta[0]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'TaForestMaps': ReportedMap(name='TaForestMaps', output_var='Ta[1]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'TaIrrigationMaps': ReportedMap(name='TaIrrigationMaps', output_var='Ta[2]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'TaMaps': ReportedMap(name='TaMaps', output_var='TaPixel', unit='mm', end=[], steps=[], all=['repE2O1','repTaMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False), + monthly=False, yearly=False, scale_factor=1, add_offset=0), 'TavgMapsOut': ReportedMap(name='TavgMapsOut', output_var='Tavg', unit='degree', end=[], steps=[], all=['repTavgMaps'], restrictoption=[], monthly=False, yearly=False), 'Theta1End': ReportedMap(name='Theta1End', output_var='Theta1a[0]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], - restrictoption=[], monthly=False, yearly=False), + restrictoption=[], monthly=False, yearly=False, scale_factor=1, add_offset=0), 'Theta1ForestEnd': ReportedMap(name='Theta1ForestEnd', output_var='Theta1a[1]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], restrictoption=[], @@ -996,12 +1009,12 @@ unit='', end=[], steps=[], all=['repThetaForestMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta1ForestState': ReportedMap(name='Theta1ForestState', output_var='Theta1a[1]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta1IrrigationEnd': ReportedMap(name='Theta1IrrigationEnd', output_var='Theta1a[2]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], @@ -1012,20 +1025,20 @@ end=[], steps=[], all=['repThetaIrrigationMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta1IrrigationState': ReportedMap(name='Theta1IrrigationState', output_var='Theta1a[2]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta1Maps': ReportedMap(name='Theta1Maps', output_var='Theta1a[0]', unit='', end=[], steps=[], all=['repThetaMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta1State': ReportedMap(name='Theta1State', output_var='Theta1a[0]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta2End': ReportedMap(name='Theta2End', output_var='Theta1b[0]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, yearly=False), @@ -1037,12 +1050,12 @@ unit='', end=[], steps=[], all=['repThetaForestMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta2ForestState': ReportedMap(name='Theta2ForestState', output_var='Theta1b[1]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta2IrrigationEnd': ReportedMap(name='Theta2IrrigationEnd', output_var='Theta1b[2]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], @@ -1053,20 +1066,20 @@ end=[], steps=[], all=['repThetaIrrigationMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta2IrrigationState': ReportedMap(name='Theta2IrrigationState', output_var='Theta1b[2]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta2Maps': ReportedMap(name='Theta2Maps', output_var='Theta1b[0]', unit='', end=[], steps=[], all=['repThetaMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta2State': ReportedMap(name='Theta2State', output_var='Theta1b[0]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta3End': ReportedMap(name='Theta3End', output_var='Theta2[0]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, yearly=False), @@ -1078,12 +1091,12 @@ unit='', end=[], steps=[], all=['repThetaForestMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta3ForestState': ReportedMap(name='Theta3ForestState', output_var='Theta2[1]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta3IrrigationEnd': ReportedMap(name='Theta3IrrigationEnd', output_var='Theta2[2]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], @@ -1093,20 +1106,20 @@ output_var='Theta2[2]', unit='', end=[], steps=[], all=['repThetaIrrigationMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta3IrrigationState': ReportedMap(name='Theta3IrrigationState', output_var='Theta2[2]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta3Maps': ReportedMap(name='Theta3Maps', output_var='Theta2[0]', unit='', end=[], steps=[], all=['repThetaMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'Theta3State': ReportedMap(name='Theta3State', output_var='Theta2[0]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'TotalAbsGroundwater': ReportedMap(name='TotalAbsGroundwater', output_var='abstraction_GW_actual_M3*self.var.M3toMM', unit='mm', end=[], steps=['repTotalAbs'], @@ -1151,17 +1164,17 @@ output_var='TotalRunoff', unit='mm', end=[], steps=[], all=['repTotalRunoffMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False), + monthly=False, yearly=False, scale_factor=1, add_offset=0), 'TotalToChanMaps': ReportedMap(name='TotalToChanMaps', output_var='ToChanM3Runoff*self.var.M3toMM', unit='mm', end=[], steps=[], all=['repTotalRunoffMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'TransLossMaps': ReportedMap(name='TransLossMaps', output_var='TransLossM3*self.var.M3toMM', unit='mm', end=[], steps=[], all=['repGwLossMaps','repE2O2'], restrictoption=['nonInit','TransLoss'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'UpstreamInflowUsedM3': ReportedMap(name='UpstreamInflowUsedM3', output_var='UpstreamInflowUsedM3', unit='M3', end=[], steps=['repWaterUse'], @@ -1182,11 +1195,11 @@ 'UZForestMaps': ReportedMap(name='UZForestMaps', output_var='UZ[1]', unit='mm', end=[], steps=[], all=['repUZMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'UZForestState': ReportedMap(name='UZForestState', output_var='UZ[1]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'UZIrrigationEnd': ReportedMap(name='UZIrrigationEnd', output_var='UZ[2]', unit='mm', end=['repEndMaps','InitLisflood'], steps=[], all=[], restrictoption=[], @@ -1194,40 +1207,41 @@ 'UZIrrigationMaps': ReportedMap(name='UZIrrigationMaps', output_var='UZ[2]', unit='mm', end=[], steps=[], all=['repUZMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False), + monthly=False, yearly=False, scale_factor=1, add_offset=0), 'UZIrrigationState': ReportedMap(name='UZIrrigationState', output_var='UZ[2]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], - monthly=False, yearly=False), + monthly=False, yearly=False, scale_factor=1, add_offset=0), 'UZMaps': ReportedMap(name='UZMaps', output_var='UZ[0]', unit='mm', end=[], steps=[], all=['repUZMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False), + monthly=False, yearly=False, scale_factor=1, add_offset=0), 'UZOutflowForestMaps': ReportedMap(name='UZOutflowForestMaps', output_var='UZOutflow[1]', unit='mm', end=[], steps=[], all=['repUZOutflowMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'UZOutflowIrrigationMaps': ReportedMap(name='UZOutflowIrrigationMaps', output_var='UZOutflow[2]', unit='mm', end=[], steps=[], all=['repUZOutflowMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'UZOutflowOtherMaps': ReportedMap(name='UZOutflowOtherMaps', output_var='UZOutflow[0]', unit='mm', end=[], steps=[], all=['repUZOutflowMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'UZOutflowMaps': ReportedMap(name='UZOutflowMaps', output_var='UZOutflowPixel', unit='mm', end=[], steps=[], all=['repUZOutflowMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'UZState': ReportedMap(name='UZState', output_var='UZ[0]', unit='mm', end=[], steps=['repStateMaps'], all=[], - restrictoption=['nonInit'], monthly=False, yearly=False), + restrictoption=['nonInit'], monthly=False, yearly=False, + scale_factor=1, add_offset=0), 'WEI_Abs': ReportedMap(name='WEI_Abs', output_var='WEI_Abs', unit='-', end=[], steps=['repWIndex'], all=[], restrictoption=['nonInit', 'wateruse', 'indicator'], @@ -1258,17 +1272,17 @@ unit='m', end=[], steps=[], all=['repWaterDepthMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False), + yearly=False, scale_factor=1, add_offset=0), 'WaterDepthState': ReportedMap(name='WaterDepthState', output_var='WaterDepth', unit='m', end=[], steps=[], all=[], restrictoption=['nonInit'], - monthly=False, yearly=False), + monthly=False, yearly=False, scale_factor=1, add_offset=0), 'TotalWaterStorageMaps': ReportedMap(name='TotalWaterStorageMaps', output_var='TotalWaterStorageMM', unit='mm', end=[], steps=[], all=['repTotalWaterStorageMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False), + monthly=False, yearly=False, scale_factor=1, add_offset=0), 'WaterSecurityIndex': ReportedMap(name='WaterSecurityIndex', output_var='WaterSecurityIndex', unit='-', end=[], steps=['repWIndex'], all=[], diff --git a/src/lisflood/global_modules/netcdf.py b/src/lisflood/global_modules/netcdf.py index 5d08ed19..49017409 100644 --- a/src/lisflood/global_modules/netcdf.py +++ b/src/lisflood/global_modules/netcdf.py @@ -439,7 +439,7 @@ def write_netcdf_header(settings, start_date, rep_steps, frequency, - ): + map_value=None): """ Writes a netcdf header without the data inside @@ -465,7 +465,11 @@ def write_netcdf_header(settings, list of reporting steps frequency: output frequency (all, monthly or yearly) - + map_value: ReportedMap namedtuple or None, optional + Output variable metadata from default_options.py. When provided and OutputPacking is + enabled, its scale_factor and add_offset attributes are used for int16 packing. + If None (default), no packing is applied. + Returns ------- object @@ -569,7 +573,22 @@ def write_netcdf_header(settings, time.units = 'minutes since %s' % start_date.strftime("%Y-%m-%d %H:%M:%S.0") nf1.variables["time"][:] = date2num(time_stamps, time.units, time.calendar) - value = nf1.createVariable(var_name, dtype, ('time', dim_lat_y, dim_lon_x), zlib=True, fill_value=-9999, chunksizes=(1, nrow, ncol)) + # value = nf1.createVariable(var_name, dtype, ('time', dim_lat_y, dim_lon_x), zlib=True, fill_value=-9999, chunksizes=(1, nrow, ncol)) + # NEW packing: + packing_enabled = binding.get('OutputPacking', 'False') == 'True' + has_packing = (map_value is not None + and getattr(map_value, 'scale_factor', None) is not None + and getattr(map_value, 'add_offset', None) is not None) + if packing_enabled and has_packing: + value = nf1.createVariable(var_name, 'i2', ('time', dim_lat_y, dim_lon_x), + zlib=True, fill_value=np.int16(-32768), + chunksizes=(1, nrow, ncol)) + value.scale_factor = np.float64(map_value.scale_factor) + value.add_offset = np.float64(map_value.add_offset) + else: + value = nf1.createVariable(var_name, dtype, ('time', dim_lat_y, dim_lon_x), + zlib=True, fill_value=-9999, chunksizes=(1, nrow, ncol)) + else: value = nf1.createVariable(var_name, dtype, (dim_lat_y, dim_lon_x), zlib=True, fill_value=-9999) diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index e238f21e..25f53b8a 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -95,7 +95,7 @@ def write(self, start_date, rep_steps): if self.data is not None: nf1 = write_netcdf_header(self.settings, self.map_name, self.map_path, self.var.DtDay, self.map_key, self.map_value.output_var, self.map_value.unit, - start_date, rep_steps, self.frequency) + start_date, rep_steps, self.frequency, map_value=self.map_value) map_np = uncompress_array(self.data) @@ -151,15 +151,35 @@ def write(self, start_date, rep_steps): if self.step_range[0] == 0: nf1 = write_netcdf_header(self.settings, self.map_name, self.map_path, self.var.DtDay, self.map_key, self.map_value.output_var, self.map_value.unit, - start_date, rep_steps, self.frequency) + start_date, rep_steps, self.frequency, map_value=self.map_value) else: nf1 = iterOpenNetcdf(self.map_path, "", 'a', format='NETCDF4') for step, data in zip(self.step_range, self.data_steps): - nf1.variables[self.map_name][step, :, :] = uncompress_array(data) + map_np = uncompress_array(data) + nc_var = nf1.variables[self.map_name] # same as before, just stored in a variable + if nc_var.dtype == np.int16: + scale = nc_var.scale_factor + offset = nc_var.add_offset + packed = np.round((map_np - offset) / scale).astype(np.float64) + # --- WARNING CHECK --- + clipped = ((packed < -32767) | (packed > 32767)) & (map_np != -9999) + if clipped.any(): + vmin = offset + scale * (-32767) + vmax = offset + scale * 32767 + warnings.warn(LisfloodWarning( + f"OutputPacking: {clipped.sum()} values in '{self.map_name}' outside " + f"packing range [{vmin:.4g}, {vmax:.4g}] and will be clipped." + )) + packed = np.clip(packed, -32767, 32767) + packed[map_np == -9999] = -32768 + nc_var.set_auto_maskandscale(False) + nc_var[step, :, :] = packed.astype(np.int16) + else: + nc_var[step, :, :] = map_np nf1.close() - + # clear lists for next chunk self.step_range.clear() self.data_steps.clear() diff --git a/src/lisfloodSettings_reference.xml b/src/lisfloodSettings_reference.xml index 2c7c7832..3798b659 100644 --- a/src/lisfloodSettings_reference.xml +++ b/src/lisfloodSettings_reference.xml @@ -211,6 +211,17 @@ You can use builtin path variables in this template and reference to other paths
+ + + The option "OutputPacking" enables CF-convention scale_factor/add_offset packing + of output maps into int16 (2 bytes per value instead of 4 or 8). + - "False" (default): write raw floating-point values (dtype from OutputMapsDataType) + - "True": pack into signed 16-bit integers using per-variable scale/offset + Readers automatically unpack using: value = packed * scale_factor + add_offset + Note: State/end maps used for warm starts are NEVER packed (always full precision). + + + ************************************************************** PARALLELISATION WITH NUMBA (USED IN ROUTING AND SOILLOOP) @@ -1839,6 +1850,7 @@ You can use builtin path variables in this template and reference to other paths + From a0fc652fb15a80f4e42d2aebdc98f9f5c6f4bc96 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Mon, 13 Jul 2026 11:25:04 +0200 Subject: [PATCH 05/36] Def Options Change --- src/lisflood/global_modules/default_options.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lisflood/global_modules/default_options.py b/src/lisflood/global_modules/default_options.py index 1add2a17..5f729301 100644 --- a/src/lisflood/global_modules/default_options.py +++ b/src/lisflood/global_modules/default_options.py @@ -370,29 +370,29 @@ 'ESActForestMaps': ReportedMap(name='ESActForestMaps', output_var='ESAct[1]', unit='mm', end=[], steps=[''], all=['repESActMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False), + monthly=False, yearly=False,scale_factor=1, add_offset=0), 'ESActMaps': ReportedMap(name='ESActMaps', output_var='ESActPixel', unit='mm', end=[], steps=[], all=['repESActMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=1, add_offset=0), + scale_factor=3.052e-4, add_offset=10.0), 'ESRefMapsOut': ReportedMap(name='ESRefMapsOut', output_var='ESRef', unit='mm', end=[], steps=[], all=['repESRefMaps'], restrictoption=[], monthly=False, yearly=False, - scale_factor=1, add_offset=0), + scale_factor=3.052e-4, add_offset=10.0), 'ETActMaps': ReportedMap(name='ETActMaps', output_var='ESActPixel+self.var.TaPixel+self.var.TaInterceptionAll+self.var.EvaAddM3*self.var.M3toMM', unit='mm', end=[], steps=[], all=['repETActMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=1, add_offset=0), + scale_factor=0.01541, add_offset=495.0), 'ETActBudykoMaps': ReportedMap(name='ETActBudykoMaps', output_var='ESActNoIrrPixel+self.var.TaNoIrrPixel+self.var.TaInterceptionNoIrrPixel', unit='mm', end=[], steps=[], all=['repETActMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=1, add_offset=0), + scale_factor=0.01541, add_offset=495.0), 'ETRefMapsOut': ReportedMap(name='ETRefMapsOut', output_var='ETRef', unit='mm', end=[], steps=[], all=['repETRefMaps'], restrictoption=[], monthly=False, yearly=False, - scale_factor=1, add_offset=0), + scale_factor=3.052e-4, add_offset=10.0), 'EWIntForestMaps': ReportedMap(name='EWIntForestMaps', output_var='TaInterception[1]', unit='mm', end=[], steps=[], all=['repEWIntMaps'], From c34f0bdc6068e4f31c023d3a4479e65774ac3856 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Mon, 13 Jul 2026 15:23:16 +0200 Subject: [PATCH 06/36] Def Options Change --- .../global_modules/default_options.py | 174 +++++++++--------- src/lisflood/global_modules/output.py | 22 ++- 2 files changed, 99 insertions(+), 97 deletions(-) diff --git a/src/lisflood/global_modules/default_options.py b/src/lisflood/global_modules/default_options.py index 5f729301..cdc03000 100644 --- a/src/lisflood/global_modules/default_options.py +++ b/src/lisflood/global_modules/default_options.py @@ -370,7 +370,7 @@ 'ESActForestMaps': ReportedMap(name='ESActForestMaps', output_var='ESAct[1]', unit='mm', end=[], steps=[''], all=['repESActMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False,scale_factor=1, add_offset=0), + monthly=False, yearly=False,scale_factor=3.052e-4, add_offset=10.), 'ESActMaps': ReportedMap(name='ESActMaps', output_var='ESActPixel', unit='mm', end=[], steps=[], all=['repESActMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, @@ -397,19 +397,19 @@ output_var='TaInterception[1]', unit='mm', end=[], steps=[], all=['repEWIntMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=3.052e-4, add_offset=10.0), 'EWIntMaps': ReportedMap(name='EWIntMaps', output_var='TaInterceptionAll', unit='mm', end=[], steps=[], all=['repEWIntMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=1, add_offset=0), + scale_factor=3.052e-4, add_offset=10.0), 'EWRefMapsOut': ReportedMap(name='EWRefMapsOut', output_var='EWRef', unit='mm', end=[], steps=[], all=['repEWRefMaps'], restrictoption=[], monthly=False, yearly=False, - scale_factor=1, add_offset=0), + scale_factor=3.052e-4, add_offset=10.0), 'EWater': ReportedMap(name='EWater', output_var='EvaAddM3*self.var.M3toMM', unit='mm', end=[], steps=[], all=['repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=1, add_offset=0), + scale_factor=3.052e-4, add_offset=10.0), 'FalkenmarkM3Capita1': ReportedMap(name='FalkenmarkM3Capita1', output_var='FalkenmarkM3Capita1', unit='M3Capita', end=[], @@ -436,7 +436,7 @@ output_var='SurfaceRunoff+self.var.UZOutflowPixel', unit='mm', end=[], steps=[], all=['repFastRunoffMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.007630, add_offset=250), 'FossilGroundwaterUsedM3': ReportedMap(name='FossilGroundwaterUsedM3', output_var='FossilGroundwaterUsedM3', unit='m3', end=[], @@ -470,49 +470,49 @@ end=[], steps=['repGwPercUZLZMaps'], all=['repGwPercUZLZMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=4.578e-5, add_offset=1.5), 'GwPercUZLZIrrigationMaps': ReportedMap(name='GwPercUZLZForestMaps', output_var='GwPercUZLZ[2]', unit='mm', end=[], steps=['repGwPercUZLZMaps'], all=['repGwPercUZLZMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=4.578e-5, add_offset=1.5), 'GwPercUZLZOtherMaps': ReportedMap(name='GwPercUZLZForestMaps', output_var='GwPercUZLZ[0]', unit='mm', end=[], steps=[], all=['repGwPercUZLZMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=4.578e-5, add_offset=1.5), 'GwPercUZLZMaps': ReportedMap(name='GwPercUZLZMaps', output_var='GwPercUZLZPixel', unit='mm', end=[], steps=[], all=['repGwPercUZLZMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=4.578e-5, add_offset=1.5), 'InfiltrationForestMaps': ReportedMap(name='InfiltrationForestMaps', output_var='Infiltration[1]', unit='mm', end=[], steps=[], all=['repInfiltrationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.007630, add_offset=250.), 'InfiltrationMaps': ReportedMap(name='InfiltrationMaps', output_var='Infiltration[0]', unit='mm', end=[], steps=[], all=['repInfiltrationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.007630, add_offset=250.), 'InterceptionForestMaps': ReportedMap(name='InterceptionForestMaps', output_var='Interception[1]', unit='mm', end=[], steps=[], all=['repInterceptionMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=2.289e-4, add_offset=7.5), 'InterceptionMaps': ReportedMap(name='InterceptionMaps', output_var='Interception[0]', unit='mm', end=[], steps=[], all=['repInterceptionMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=2.289e-4, add_offset=7.5), 'LocalFreshwaterM3': ReportedMap(name='LocalFreshwaterM3', output_var='LocalFreshwaterM3', unit='m3', end=[], @@ -540,16 +540,16 @@ restrictoption=[], monthly=False, yearly=False), 'LZMaps': ReportedMap(name='LZMaps', output_var='LZ', unit='mm', end=[], steps=[], all=['repLZMaps', 'repE2O2'], restrictoption=['nonInit'], - monthly=False, yearly=False), + monthly=False, yearly=False,scale_factor=0.09156, add_offset=-1000.0), 'LZOutflowMaps': ReportedMap(name='LZOutflowMaps', output_var='LZOutflowToChannelPixel', unit='mm', end=[], steps=[], all=['repLZOutflowMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor= 4.578e-5, add_offset=1.5), 'LZState': ReportedMap(name='LZState', output_var='LZ', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=1, add_offset=0), + scale_factor=0.09156, add_offset=-1000.0), 'LakeAbstractionM3': ReportedMap(name='LakeAbstractionM3', output_var='LakeAbstractionM3', unit='m3', end=[], steps=['repTotalAbs'], all=[], @@ -610,15 +610,15 @@ 'MonthETactMM': ReportedMap(name='MonthETactMM', output_var='MonthETactMM', unit='mm', end=[], steps=['repWIndex'], all=[], restrictoption=['nonInit', 'wateruse', 'indicator'], - monthly=False, yearly=False, scale_factor=1, add_offset=0), + monthly=False, yearly=False), 'MonthETdifMM': ReportedMap(name='MonthETdifMM', output_var='MonthETdifMM', unit='mm', end=[], steps=['repWIndex'], all=[], restrictoption=['nonInit', 'wateruse', 'indicator'], - monthly=False, yearly=False, scale_factor=1, add_offset=0), + monthly=False, yearly=False), 'MonthETpotMM': ReportedMap(name='MonthETpotMM', output_var='MonthETpotMM', unit='mm', end=[], steps=['repWIndex'], all=[], restrictoption=['nonInit', 'wateruse', 'indicator'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False), 'TimeSinceStartPrerunChunkEnd': ReportedMap(name='TimeSinceStartPrerunChunkEnd', output_var='TimeSinceStartPrerunChunk', unit='number of steps', end=['InitLisflood'], @@ -708,34 +708,34 @@ output_var='SeepTopToSubA[0]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=4.578e-5, add_offset=1.5), 'Percolation1ato1bForestMaps': ReportedMap(name='Percolation1ato1bForestMaps', output_var='SeepTopToSubA[1]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=4.578e-5, add_offset=1.5), 'Percolation1ato1bIrrigationMaps': ReportedMap(name='Percolation1ato1bIrrigationMaps', output_var='SeepTopToSubA[2]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=4.578e-5, add_offset=1.5), 'Percolation1bto2OtherMaps': ReportedMap(name='Percolation1bto2OtherMaps', output_var='SeepTopToSubB[0]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=4.578e-5, add_offset=1.5), 'Percolation1bto2ForestMaps': ReportedMap(name='Percolation1bto2ForestMaps', output_var='SeepTopToSubB[1]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=4.578e-5, add_offset=1.5), 'Percolation1bto2IrrigationMaps': ReportedMap(name='Percolation1bto2IrrigationMaps', output_var='SeepTopToSubB[2]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=4.578e-5, add_offset=1.5), 'PrevCmMCTEnd': ReportedMap(name='PrevCmMCTEnd', output_var='PrevCm0', unit='-', end=['repEndMaps'], steps=[], all=[], restrictoption=['nonInit','MCTRouting'], monthly=False, yearly=False), @@ -770,7 +770,7 @@ unit='mm/timestep', end=[], steps=[], all=['repPrecipitationMaps'], restrictoption=[], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.01068, add_offset=350.), 'PrefFlowOtherMaps': ReportedMap(name='PrefFlowOtherMaps', output_var='PrefFlow[0]', unit='mm', end=[], steps=[], all=['repPrefFlowMaps'], @@ -793,7 +793,7 @@ 'RainMaps': ReportedMap(name='RainMaps', output_var='Rain', unit='mm', end=[], steps=[], all=['repRainMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=1, add_offset=0), + scale_factor=0.01068, add_offset=350.), 'RegionMonthExternalInflowM3': ReportedMap(name='RegionMonthExternalInflowM3', output_var='RegionMonthExternalInflowM3', unit='M3', end=[], @@ -891,116 +891,116 @@ unit='days', end=[], steps=[], all=['repStressDays'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False), 'SMStressMap': ReportedMap(name='SMStressMap', output_var='SoilMoistureStressDays[0]', unit='days', end=[], steps=[], all=['repStressDays'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False), 'SeepSubToGWotherMaps': ReportedMap(name='SeepSubToGWOtherMaps', output_var='SeepSubToGW[0]', unit='mm', end=[], steps=[], all=['repSeepSubToGWMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=9.156e-4, add_offset=30.), 'SeepSubToGWforestMaps': ReportedMap(name='SeepSubToGWForestMaps', output_var='SeepSubToGW[1]', unit='mm', end=[], steps=[], all=['repSeepSubToGWMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=9.156e-4, add_offset=30.), 'SeepSubToGWirrigationMaps': ReportedMap(name='SeepSubToGWIrrigationMaps', output_var='SeepSubToGW[2]', unit='mm', end=[], steps=[], all=['repSeepSubToGWMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=9.156e-4, add_offset=30.), 'SeepSubToGWMaps': ReportedMap(name='SeepSubToGWMaps', output_var='SeepSubToGWPixel', unit='mm', end=[], steps=[], all=['repSeepSubToGWMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=9.156e-4, add_offset=30.), 'SeepTopToSubBAverageOtherMap': ReportedMap(name='SeepTopToSubBAverageOtherMap', output_var='SeepTopToSubBAv[0]', unit='mm/timestep', end=['InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=9.156e-4, add_offset=30.), 'SeepTopToSubBAverageForestMap': ReportedMap(name='SeepTopToSubBAverageForestMap', output_var='SeepTopToSubBAv[1]', unit='mm/timestep', end=['InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=9.156e-4, add_offset=30.), 'SeepTopToSubBAverageIrrigationMap': ReportedMap(name='SeepTopToSubBAverageIrrigationMap', output_var='SeepTopToSubBAv[2]', unit='mm/timestep', end=['InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=9.156e-4, add_offset=30.), 'SnowCoverAEnd': ReportedMap(name='SnowCoverAEnd', output_var='SnowCoverS[0]', unit='mm', end=['repEndMaps'], steps=[], all=[], restrictoption=[], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False), 'SnowCoverAState': ReportedMap(name='SnowCoverAState', output_var='SnowCoverS[0]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.15260, add_offset=5000.), 'SnowCoverBEnd': ReportedMap(name='SnowCoverBEnd', output_var='SnowCoverS[1]', unit='mm', end=['repEndMaps'], steps=[], all=[], restrictoption=[], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False), 'SnowCoverBState': ReportedMap(name='SnowCoverBState', output_var='SnowCoverS[1]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.15260, add_offset=5000.), 'SnowCoverCEnd': ReportedMap(name='SnowCoverCEnd', output_var='SnowCoverS[2]', unit='mm', end=['repEndMaps'], steps=[], all=[], restrictoption=[], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False), 'SnowCoverCState': ReportedMap(name='SnowCoverCState', output_var='SnowCoverS[2]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.15260, add_offset=5000.), 'SnowCoverMaps': ReportedMap(name='SnowCoverMaps', output_var='SnowCover', unit='mm', end=[], steps=[], all=['repSnowCoverMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.15260, add_offset=5000.), 'SnowMaps': ReportedMap(name='SnowMaps', output_var='Snow', unit='mm', end=[], steps=[], all=['repSnowMaps'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=1, add_offset=0), + scale_factor=0.003052, add_offset=100.), 'SnowMeltMaps': ReportedMap(name='SnowMeltMaps', output_var='SnowMelt', unit='mm', end=[], steps=[], all=['repSnowMeltMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.003815, add_offset=125.), 'SurfaceRunoffMaps': ReportedMap(name='SurfaceRunoffMaps', output_var='SurfaceRunoff', unit='mm', end=[], steps=[], all=['repSurfaceRunoffMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.007630, add_offset=250.), 'TaOtherMaps': ReportedMap(name='TaOtherMaps', output_var='Ta[0]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=2.289e-4, add_offset=7.5), 'TaForestMaps': ReportedMap(name='TaForestMaps', output_var='Ta[1]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=2.289e-4, add_offset=7.5), 'TaIrrigationMaps': ReportedMap(name='TaIrrigationMaps', output_var='Ta[2]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=2.289e-4, add_offset=7.5), 'TaMaps': ReportedMap(name='TaMaps', output_var='TaPixel', unit='mm', end=[], steps=[], all=['repE2O1','repTaMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=1, add_offset=0), + monthly=False, yearly=False, scale_factor=2.289e-4, add_offset=7.5), 'TavgMapsOut': ReportedMap(name='TavgMapsOut', output_var='Tavg', unit='degree', end=[], steps=[], all=['repTavgMaps'], restrictoption=[], monthly=False, yearly=False), 'Theta1End': ReportedMap(name='Theta1End', output_var='Theta1a[0]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], - restrictoption=[], monthly=False, yearly=False, scale_factor=1, add_offset=0), + restrictoption=[], monthly=False, yearly=False), 'Theta1ForestEnd': ReportedMap(name='Theta1ForestEnd', output_var='Theta1a[1]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], restrictoption=[], @@ -1009,12 +1009,12 @@ unit='', end=[], steps=[], all=['repThetaForestMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta1ForestState': ReportedMap(name='Theta1ForestState', output_var='Theta1a[1]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta1IrrigationEnd': ReportedMap(name='Theta1IrrigationEnd', output_var='Theta1a[2]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], @@ -1025,20 +1025,20 @@ end=[], steps=[], all=['repThetaIrrigationMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta1IrrigationState': ReportedMap(name='Theta1IrrigationState', output_var='Theta1a[2]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta1Maps': ReportedMap(name='Theta1Maps', output_var='Theta1a[0]', unit='', end=[], steps=[], all=['repThetaMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta1State': ReportedMap(name='Theta1State', output_var='Theta1a[0]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta2End': ReportedMap(name='Theta2End', output_var='Theta1b[0]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, yearly=False), @@ -1050,12 +1050,12 @@ unit='', end=[], steps=[], all=['repThetaForestMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta2ForestState': ReportedMap(name='Theta2ForestState', output_var='Theta1b[1]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta2IrrigationEnd': ReportedMap(name='Theta2IrrigationEnd', output_var='Theta1b[2]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], @@ -1066,20 +1066,20 @@ end=[], steps=[], all=['repThetaIrrigationMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta2IrrigationState': ReportedMap(name='Theta2IrrigationState', output_var='Theta1b[2]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta2Maps': ReportedMap(name='Theta2Maps', output_var='Theta1b[0]', unit='', end=[], steps=[], all=['repThetaMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta2State': ReportedMap(name='Theta2State', output_var='Theta1b[0]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta3End': ReportedMap(name='Theta3End', output_var='Theta2[0]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, yearly=False), @@ -1091,12 +1091,12 @@ unit='', end=[], steps=[], all=['repThetaForestMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta3ForestState': ReportedMap(name='Theta3ForestState', output_var='Theta2[1]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta3IrrigationEnd': ReportedMap(name='Theta3IrrigationEnd', output_var='Theta2[2]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], @@ -1106,20 +1106,20 @@ output_var='Theta2[2]', unit='', end=[], steps=[], all=['repThetaIrrigationMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta3IrrigationState': ReportedMap(name='Theta3IrrigationState', output_var='Theta2[2]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta3Maps': ReportedMap(name='Theta3Maps', output_var='Theta2[0]', unit='', end=[], steps=[], all=['repThetaMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'Theta3State': ReportedMap(name='Theta3State', output_var='Theta2[0]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=1.526e-5, add_offset=0.5), 'TotalAbsGroundwater': ReportedMap(name='TotalAbsGroundwater', output_var='abstraction_GW_actual_M3*self.var.M3toMM', unit='mm', end=[], steps=['repTotalAbs'], @@ -1164,17 +1164,17 @@ output_var='TotalRunoff', unit='mm', end=[], steps=[], all=['repTotalRunoffMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=1, add_offset=0), + monthly=False, yearly=False, scale_factor=0.007630, add_offset=250.), 'TotalToChanMaps': ReportedMap(name='TotalToChanMaps', output_var='ToChanM3Runoff*self.var.M3toMM', unit='mm', end=[], steps=[], all=['repTotalRunoffMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.005341, add_offset=175.), 'TransLossMaps': ReportedMap(name='TransLossMaps', output_var='TransLossM3*self.var.M3toMM', unit='mm', end=[], steps=[], all=['repGwLossMaps','repE2O2'], restrictoption=['nonInit','TransLoss'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.009156, add_offset=300.), 'UpstreamInflowUsedM3': ReportedMap(name='UpstreamInflowUsedM3', output_var='UpstreamInflowUsedM3', unit='M3', end=[], steps=['repWaterUse'], @@ -1195,53 +1195,53 @@ 'UZForestMaps': ReportedMap(name='UZForestMaps', output_var='UZ[1]', unit='mm', end=[], steps=[], all=['repUZMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.05341, add_offset=1750.), 'UZForestState': ReportedMap(name='UZForestState', output_var='UZ[1]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.05341, add_offset=1750.), 'UZIrrigationEnd': ReportedMap(name='UZIrrigationEnd', output_var='UZ[2]', unit='mm', end=['repEndMaps','InitLisflood'], steps=[], all=[], restrictoption=[], - monthly=False, yearly=False), + monthly=False, yearly=False,), 'UZIrrigationMaps': ReportedMap(name='UZIrrigationMaps', output_var='UZ[2]', unit='mm', end=[], steps=[], all=['repUZMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=1, add_offset=0), + monthly=False, yearly=False, scale_factor=0.05341, add_offset=1750.), 'UZIrrigationState': ReportedMap(name='UZIrrigationState', output_var='UZ[2]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=1, add_offset=0), + monthly=False, yearly=False, scale_factor=0.05341, add_offset=1750.), 'UZMaps': ReportedMap(name='UZMaps', output_var='UZ[0]', unit='mm', end=[], steps=[], all=['repUZMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=1, add_offset=0), + monthly=False, yearly=False, scale_factor=0.05341, add_offset=1750.), 'UZOutflowForestMaps': ReportedMap(name='UZOutflowForestMaps', output_var='UZOutflow[1]', unit='mm', end=[], steps=[], all=['repUZOutflowMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.004578, add_offset=150.), 'UZOutflowIrrigationMaps': ReportedMap(name='UZOutflowIrrigationMaps', output_var='UZOutflow[2]', unit='mm', end=[], steps=[], all=['repUZOutflowMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.004578, add_offset=150.), 'UZOutflowOtherMaps': ReportedMap(name='UZOutflowOtherMaps', output_var='UZOutflow[0]', unit='mm', end=[], steps=[], all=['repUZOutflowMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.004578, add_offset=150.), 'UZOutflowMaps': ReportedMap(name='UZOutflowMaps', output_var='UZOutflowPixel', unit='mm', end=[], steps=[], all=['repUZOutflowMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.004578, add_offset=150.), 'UZState': ReportedMap(name='UZState', output_var='UZ[0]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=1, add_offset=0), + scale_factor=0.05341, add_offset=1750.), 'WEI_Abs': ReportedMap(name='WEI_Abs', output_var='WEI_Abs', unit='-', end=[], steps=['repWIndex'], all=[], restrictoption=['nonInit', 'wateruse', 'indicator'], @@ -1272,17 +1272,17 @@ unit='m', end=[], steps=[], all=['repWaterDepthMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1, add_offset=0), + yearly=False, scale_factor=0.003815, add_offset=125.), 'WaterDepthState': ReportedMap(name='WaterDepthState', output_var='WaterDepth', unit='m', end=[], steps=[], all=[], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=1, add_offset=0), + monthly=False, yearly=False, scale_factor=0.003815, add_offset=125.), 'TotalWaterStorageMaps': ReportedMap(name='TotalWaterStorageMaps', output_var='TotalWaterStorageMM', unit='mm', end=[], steps=[], all=['repTotalWaterStorageMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=1, add_offset=0), + monthly=False, yearly=False, scale_factor=534.4, add_offset=17497500.0), 'WaterSecurityIndex': ReportedMap(name='WaterSecurityIndex', output_var='WaterSecurityIndex', unit='-', end=[], steps=['repWIndex'], all=[], diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index 25f53b8a..e0e39e2c 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -155,14 +155,18 @@ def write(self, start_date, rep_steps): else: nf1 = iterOpenNetcdf(self.map_path, "", 'a', format='NETCDF4') + nc_var = nf1.variables[self.map_name] + nc_var.set_auto_maskandscale(False) + is_packed = nc_var.dtype == np.int16 + if is_packed: + nc_var.set_auto_maskandscale(False) + scale = nc_var.scale_factor + offset = nc_var.add_offset + for step, data in zip(self.step_range, self.data_steps): map_np = uncompress_array(data) - nc_var = nf1.variables[self.map_name] # same as before, just stored in a variable - if nc_var.dtype == np.int16: - scale = nc_var.scale_factor - offset = nc_var.add_offset + if is_packed: packed = np.round((map_np - offset) / scale).astype(np.float64) - # --- WARNING CHECK --- clipped = ((packed < -32767) | (packed > 32767)) & (map_np != -9999) if clipped.any(): vmin = offset + scale * (-32767) @@ -170,17 +174,15 @@ def write(self, start_date, rep_steps): warnings.warn(LisfloodWarning( f"OutputPacking: {clipped.sum()} values in '{self.map_name}' outside " f"packing range [{vmin:.4g}, {vmax:.4g}] and will be clipped." - )) + )) packed = np.clip(packed, -32767, 32767) packed[map_np == -9999] = -32768 - nc_var.set_auto_maskandscale(False) nc_var[step, :, :] = packed.astype(np.int16) else: - nc_var[step, :, :] = map_np + nc_var[step, :, :] = map_np nf1.close() - - # clear lists for next chunk + self.step_range.clear() self.data_steps.clear() else: From d2d60664d6b7e3e688008ee9a67c041980e7f956 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Mon, 13 Jul 2026 15:29:45 +0200 Subject: [PATCH 07/36] Def Options Change --- src/lisflood/global_modules/output.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index e0e39e2c..1d79a61a 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -18,6 +18,7 @@ import numpy as np from pcraster import ifthen, catchmenttotal, mapmaximum import sys +import warnings from .zusatz import TimeoutputTimeseries from .add1 import decompress, valuecell, loadmap, compressArray From 757061b8c580f32a5efabe2940cb2f8e09f0b8c7 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Mon, 13 Jul 2026 15:39:59 +0200 Subject: [PATCH 08/36] Def Options Change --- src/lisflood/global_modules/default_options.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lisflood/global_modules/default_options.py b/src/lisflood/global_modules/default_options.py index cdc03000..a10fa039 100644 --- a/src/lisflood/global_modules/default_options.py +++ b/src/lisflood/global_modules/default_options.py @@ -770,7 +770,7 @@ unit='mm/timestep', end=[], steps=[], all=['repPrecipitationMaps'], restrictoption=[], monthly=False, - yearly=False, scale_factor=0.01068, add_offset=350.), + yearly=False, scale_factor=0.01526, add_offset=500.), 'PrefFlowOtherMaps': ReportedMap(name='PrefFlowOtherMaps', output_var='PrefFlow[0]', unit='mm', end=[], steps=[], all=['repPrefFlowMaps'], @@ -793,7 +793,7 @@ 'RainMaps': ReportedMap(name='RainMaps', output_var='Rain', unit='mm', end=[], steps=[], all=['repRainMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=0.01068, add_offset=350.), + scale_factor=0.01526, add_offset=500.), 'RegionMonthExternalInflowM3': ReportedMap(name='RegionMonthExternalInflowM3', output_var='RegionMonthExternalInflowM3', unit='M3', end=[], From 081ec5ef54cbe63376f9b70678c45b20681fa6c1 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Mon, 13 Jul 2026 16:19:52 +0200 Subject: [PATCH 09/36] Def Options Change --- src/lisflood/global_modules/output.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index 1d79a61a..d4622a83 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -26,6 +26,13 @@ from .errors import LisfloodFileError, LisfloodWarning from .settings import inttodate, CDFFlags, LisSettings +# ------------------------------------------------------------------------ +# Packing constants for int16 CF scale/offset encoding +# ------------------------------------------------------------------------ +_INT16_INFO = np.iinfo(np.int16) +PACK_FILL = np.int16(_INT16_INFO.min) # -32768 +PACK_MIN = _INT16_INFO.min + 1 # -32767 +PACK_MAX = _INT16_INFO.max # 32767 # ------------------------------------------------------------------------ # Writer classes @@ -176,8 +183,8 @@ def write(self, start_date, rep_steps): f"OutputPacking: {clipped.sum()} values in '{self.map_name}' outside " f"packing range [{vmin:.4g}, {vmax:.4g}] and will be clipped." )) - packed = np.clip(packed, -32767, 32767) - packed[map_np == -9999] = -32768 + packed = np.clip(packed, PACK_MIN, PACK_MAX) + packed[map_np == -9999] = PACK_FILL nc_var[step, :, :] = packed.astype(np.int16) else: nc_var[step, :, :] = map_np From 33e8d55fd0c096d28d77d6efe89e9eaeca426919 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 14 Jul 2026 18:13:01 +0200 Subject: [PATCH 10/36] Updates to default options and fill values --- packing_scale_offset_values.md | 134 +++++++++++--------------- src/lisflood/global_modules/output.py | 12 ++- 2 files changed, 61 insertions(+), 85 deletions(-) diff --git a/packing_scale_offset_values.md b/packing_scale_offset_values.md index 86f49f42..859b85b3 100644 --- a/packing_scale_offset_values.md +++ b/packing_scale_offset_values.md @@ -1,83 +1,57 @@ -# Scale/Offset Packing Values for LISFLOOD Output Variables - -Based on actual GloFAS global run min/max values, with ~20-50% headroom above observed max. - -Formula: `scale_factor = (vmax - vmin) / 65534`, `add_offset = vmin + scale_factor * 32767` - -Only time-series outputs (Maps/All) are listed. State/End maps should NOT be packed. - -| Variable | Unit | Obs Min | Obs Max | Design Min | Design Max | scale_factor | add_offset | Precision (±) | -|----------|------|---------|---------|------------|------------|--------------|------------|---------------| -| dis (DischargeMaps) | m3/s | 0 | 2.93e5 | 0 | 400000 | 6.1040 | 200000.0 | ±3.05 m3/s | -| chanq | m3/s | 0 | 2.93e5 | 0 | 400000 | 6.1040 | 200000.0 | ±3.05 m3/s | -| chanqavgdt | m3/s | 0 | 2.93e5 | 0 | 400000 | 6.1040 | 200000.0 | ±3.05 m3/s | -| chcro (CrossSectionArea) | m2 | 0 | 9.89e7 | 0 | 1.5e8 | 2288.4 | 75000000.0 | ±1144 m2 | -| tws (TotalWaterStorage) | mm | -2396 | 2.69e7 | -5000 | 3.5e7 | 534.4 | 17497500.0 | ±267 mm | -| lz (LowerZone) | mm | -2886 | 1415 | -4000 | 2000 | 0.09156 | -1000.0 | ±0.046 mm | -| uz, uzf, uzi | mm | 0 | 2486 | 0 | 3500 | 0.05341 | 1750.0 | ±0.027 mm | -| scov (SnowCover) | mm | 0 | 5359 | 0 | 8000 | 0.12207 | 4000.0 | ±0.061 mm | -| scova, scovb, scovc | mm | 0 | 6819 | 0 | 10000 | 0.15260 | 5000.0 | ±0.076 mm | -| rain | mm/day | 0 | 509 | 0 | 700 | 0.01068 | 350.0 | ±0.005 mm | -| snow | mm/day | 0 | 132 | 0 | 200 | 0.003052 | 100.0 | ±0.0015 mm | -| smelt (SnowMelt) | mm/day | 0 | 167 | 0 | 250 | 0.003815 | 125.0 | ±0.0019 mm | -| etact (ETactual) | mm/day | -6.3 | 828 | -10 | 1000 | 0.01541 | 495.0 | ±0.0077 mm | -| tact, tactF | mm/day | -6.4 | 7.7 | -10 | 15 | 3.815e-4 | 2.5 | ±0.00019 mm | -| Ta_other | mm/day | 0 | 7.4 | 0 | 15 | 2.289e-4 | 7.5 | ±0.00011 mm | -| esact, esactF | mm/day | 0 | 11.4 | 0 | 20 | 3.052e-4 | 10.0 | ±0.00015 mm | -| dirrun (DirectRunoff) | mm | 0 | 255 | 0 | 400 | 0.006104 | 200.0 | ±0.003 mm | -| srun (SurfaceRunoff) | mm | 0 | 330 | 0 | 500 | 0.007630 | 250.0 | ±0.0038 mm | -| trun (TotalRunoff) | mm | 0 | 331 | 0 | 500 | 0.007630 | 250.0 | ±0.0038 mm | -| inf, infF (Infiltration) | mm | 0 | 314 | 0 | 500 | 0.007630 | 250.0 | ±0.0038 mm | -| pflow, pflowF, pflowO, pflowi | mm | 0 | 293 | 0 | 400 | 0.006104 | 200.0 | ±0.003 mm | -| quz, quzF, quzI, quzO | mm | 0 | 209 | 0 | 300 | 0.004578 | 150.0 | ±0.0023 mm | -| qlz | mm | 0 | 2.0 | 0 | 3 | 4.578e-5 | 1.5 | ±2.3e-5 mm | -| uz2lz, uz2lzF | mm | 0 | 2.0 | 0 | 3 | 4.578e-5 | 1.5 | ±2.3e-5 mm | -| gwloss | mm | 0 | 1.0 | 0 | 2 | 3.052e-5 | 1.0 | ±1.5e-5 mm | -| sgwF, sgwIrrigation, sgwOther, sgwPixel | mm | 0 | 40 | 0 | 60 | 9.156e-4 | 30.0 | ±4.6e-4 mm | -| frost (FrostIndex) | - | 0 | 57 | 0 | 100 | 0.001526 | 50.0 | ±7.6e-4 | -| dslr, dslrf, dslri | days | 1 | 2558 | 0 | 4000 | 0.06104 | 2000.0 | ±0.031 days | -| cseal (CumInterSealed) | mm | 0 | 1.0 | 0 | 1.5 | 2.289e-5 | 0.75 | ±1.1e-5 mm | -| tha, thb, thc, thfa-thic (theta) | - | 0.04 | 0.70 | 0 | 1.0 | 1.526e-5 | 0.5 | ±7.6e-6 | -| ofdir (OFDirectM3) | m3 | 0 | 1.76e6 | 0 | 2.5e6 | 38.15 | 1250000.0 | ±19 m3 | -| offor (OFForestM3) | m3 | 0 | 5.08e6 | 0 | 7.0e6 | 106.8 | 3500000.0 | ±53 m3 | -| ofoth (OFOtherM3) | m3 | 0 | 2.90e6 | 0 | 4.0e6 | 61.04 | 2000000.0 | ±31 m3 | -| wdept (WaterDepth) | mm | 0 | 168 | 0 | 250 | 0.003815 | 125.0 | ±0.0019 mm | -| transloss | mm | 0 | 412 | 0 | 600 | 0.009156 | 300.0 | ±0.0046 mm | -| ttoc (ToChanRunoff) | mm | 0 | 235 | 0 | 350 | 0.005341 | 175.0 | ±0.0027 mm | -| lakeh | m | 0 | 39.5 | 0 | 60 | 9.156e-4 | 30.0 | ±4.6e-4 m | -| lakeprevinq, lakeprevoutq | m3/s | 0 | 1.06e5 | 0 | 150000 | 2.289 | 75000.0 | ±1.14 m3/s | -| rsfil (ReservoirFill) | - | 0 | 0.98 | 0 | 1.5 | 2.289e-5 | 0.75 | ±1.1e-5 | - +# Scale/Offset Packing Values — Current Implementation + +CF-convention int16 packing as implemented in `default_options.py`. +Formula: `unpacked = packed * scale_factor + add_offset` +Precision = scale_factor / 2 + +## Packed Variables (Maps outputs) + +| Variable(s) | Unit | Design Range | scale_factor | add_offset | Precision (±) | +|-------------|------|--------------|--------------|------------|---------------| +| DischargeMaps | m3/s | 0 – 400,000 | 6.104 | 200000.0 | ±3.05 m3/s | +| DirectRunoffMaps | mm | 0 – 400 | 0.006104 | 200.0 | ±0.003 mm | +| ESActForestMaps, ESActMaps, ESRefMapsOut | mm | 0 – 20 | 3.052e-4 | 10.0 | ±1.5e-4 mm | +| ETActMaps, ETActBudykoMaps | mm | -10 – 1000 | 0.01541 | 495.0 | ±0.0077 mm | +| ETRefMapsOut | mm | 0 – 20 | 3.052e-4 | 10.0 | ±1.5e-4 mm | +| EWIntForestMaps, EWIntMaps | mm | 0 – 20 | 3.052e-4 | 10.0 | ±1.5e-4 mm | +| EWRefMapsOut, EWater | mm | 0 – 20 | 3.052e-4 | 10.0 | ±1.5e-4 mm | +| FastRunoffMaps | mm | 0 – 500 | 0.007630 | 250.0 | ±0.0038 mm | +| GwPercUZLZ (all variants) | mm | 0 – 3 | 4.578e-5 | 1.5 | ±2.3e-5 mm | +| InfiltrationForestMaps, InfiltrationMaps | mm | 0 – 500 | 0.007630 | 250.0 | ±0.0038 mm | +| InterceptionForestMaps, InterceptionMaps | mm | 0 – 15 | 2.289e-4 | 7.5 | ±1.1e-4 mm | +| MonthETactMM | mm | 0 – 300 | 0.004578 | 150.0 | ±0.0023 mm | +| MonthETdifMM | mm | -300 – 300 | 0.009156 | 0.0 | ±0.0046 mm | +| MonthETpotMM | mm | 0 – 300 | 0.004578 | 150.0 | ±0.0023 mm | +| PrecipitationMaps, RainMaps | mm | 0 – 1000 | 0.01526 | 500.0 | ±0.0076 mm | +| PrefFlow (all variants) | mm | 0 – 400 | 0.006104 | 200.0 | ±0.003 mm | +| SeepSubToGWMaps | mm | 0 – 60 | 9.156e-4 | 30.0 | ±4.6e-4 mm | +| SnowCoverMaps | mm | 0 – 10000 | 0.15260 | 5000.0 | ±0.076 mm | +| SnowMaps | mm | 0 – 200 | 0.003052 | 100.0 | ±0.0015 mm | +| SnowMeltMaps | mm | 0 – 250 | 0.003815 | 125.0 | ±0.0019 mm | +| SurfaceRunoffMaps | mm | 0 – 500 | 0.007630 | 250.0 | ±0.0038 mm | +| TaOtherMaps, TaForestMaps, TaIrrigationMaps, TaMaps | mm | -10 – 15 | 3.815e-4 | 2.5 | ±1.9e-4 mm | +| Theta (all Maps variants: 1/2/3, Other/Forest/Irrigation) | - | 0 – 1 | 1.526e-5 | 0.5 | ±7.6e-6 | +| TotalRunoffMaps, TotalToChanMaps | mm | 0 – 500 | 0.007630 | 250.0 | ±0.0038 mm | +| TransLossMaps | mm | 0 – 600 | 0.009156 | 300.0 | ±0.0046 mm | +| UZForestMaps, UZIrrigationMaps, UZMaps | mm | 0 – 3500 | 0.05341 | 1750.0 | ±0.027 mm | +| UZOutflow (all variants) | mm | 0 – 300 | 0.004578 | 150.0 | ±0.0023 mm | +| WaterDepthMaps | mm | 0 – 250 | 0.003815 | 125.0 | ±0.0019 mm | + +## NOT Packed (scale_factor = None) + +These variables have no packing defined and will always be written as float: + +- All `*End` maps (End maps — warm start, full precision needed) +- All `*State` maps (State maps — warm start, full precision needed) +- TotalWaterStorageMaps (range too large for useful int16 precision) +- TavgMapsOut (temperature — no packing defined) +- All water use / indicator variables (monthly aggregations, various ranges) +- FalkenmarkM3Capita1, EFlowIndicator, etc. (specialized indicators) ## Notes -### Design range choices -- Headroom of 20-50% above observed max to accommodate extreme events not seen in the calibration run -- For variables with observed min = 0, design min is kept at 0 (physical lower bound) -- For lz (can go negative due to abstractions), design min set to -4000 based on observed -2886 -- For tws (huge dynamic range 0 to 27M): precision is coarse (±267 mm) — consider whether this variable really needs map output or if TSS at gauges suffices - -### Variables NOT recommended for packing -- `tws` (TotalWaterStorage): extreme dynamic range makes int16 precision poor. Use float32 instead. -- `chcro` (CrossSectionArea): same issue — range 0 to 1.5e8 gives ±1144 m2 precision -- All `.end` and `State` variables: used for warm start, need full precision - -### How to use these values in `default_options.py` - -```python -'DischargeMaps': ReportedMap(name='DischargeMaps', output_var='ChanQAvg', - unit='m3/s', end=[], steps=[], - all=['repDischargeMaps'], restrictoption=[], - monthly=False, yearly=False, - scale_factor=6.1040, add_offset=200000.0), -``` - -### Verification -After implementation, verify with: -```python -# For discharge: design range 0-400000 -# packed = round((value - 200000) / 6.1040) -# At value=0: packed = -32767 ✓ (min int16 usable) -# At value=400000: packed = +32767 ✓ (max int16 usable) -# At value=200000: packed = 0 ✓ (midpoint) -``` +- Packing is only active when `OutputPacking = True` in settings XML +- All values derived from GloFAS global run observed min/max with 20-50% headroom +- Theta uses theoretical range 0–1 (physically bounded) +- Precision column shows maximum quantization error (half a scale_factor step) +- Clipping warning fires once per variable if values exceed design range diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index d4622a83..cf22d9d4 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -25,14 +25,15 @@ from .netcdf import write_netcdf_header, iterOpenNetcdf, nanCheckMap, uncompress_array from .errors import LisfloodFileError, LisfloodWarning from .settings import inttodate, CDFFlags, LisSettings +from netCDF4 import default_fillvals + # ------------------------------------------------------------------------ # Packing constants for int16 CF scale/offset encoding # ------------------------------------------------------------------------ -_INT16_INFO = np.iinfo(np.int16) -PACK_FILL = np.int16(_INT16_INFO.min) # -32768 -PACK_MIN = _INT16_INFO.min + 1 # -32767 -PACK_MAX = _INT16_INFO.max # 32767 +PACK_FILL = np.int16(default_fillvals['i2']) # -32767 +PACK_MIN = PACK_FILL + 1 # -32766 +PACK_MAX = np.iinfo(np.int16).max # 32767 # ------------------------------------------------------------------------ # Writer classes @@ -170,6 +171,7 @@ def write(self, start_date, rep_steps): nc_var.set_auto_maskandscale(False) scale = nc_var.scale_factor offset = nc_var.add_offset + nodata_mask = MaskInfo.instance().info.mask for step, data in zip(self.step_range, self.data_steps): map_np = uncompress_array(data) @@ -184,7 +186,7 @@ def write(self, start_date, rep_steps): f"packing range [{vmin:.4g}, {vmax:.4g}] and will be clipped." )) packed = np.clip(packed, PACK_MIN, PACK_MAX) - packed[map_np == -9999] = PACK_FILL + packed[nodata_mask] = PACK_FILL nc_var[step, :, :] = packed.astype(np.int16) else: nc_var[step, :, :] = map_np From 964a24a04e60e430df59fbe2f8b0183eff6d6e88 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 14 Jul 2026 18:24:14 +0200 Subject: [PATCH 11/36] Updates to default options and fill values --- src/lisflood/global_modules/output.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index cf22d9d4..14687989 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -24,7 +24,7 @@ from .add1 import decompress, valuecell, loadmap, compressArray from .netcdf import write_netcdf_header, iterOpenNetcdf, nanCheckMap, uncompress_array from .errors import LisfloodFileError, LisfloodWarning -from .settings import inttodate, CDFFlags, LisSettings +from .settings import inttodate, CDFFlags, LisSettings, MaskInfo from netCDF4 import default_fillvals From 12e4b1ba2fb2c56e224898c6b2b98d9ac9ca88b5 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Fri, 17 Jul 2026 12:39:00 +0200 Subject: [PATCH 12/36] Update fill value --- src/lisflood/global_modules/netcdf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lisflood/global_modules/netcdf.py b/src/lisflood/global_modules/netcdf.py index 49017409..df544a69 100644 --- a/src/lisflood/global_modules/netcdf.py +++ b/src/lisflood/global_modules/netcdf.py @@ -581,7 +581,7 @@ def write_netcdf_header(settings, and getattr(map_value, 'add_offset', None) is not None) if packing_enabled and has_packing: value = nf1.createVariable(var_name, 'i2', ('time', dim_lat_y, dim_lon_x), - zlib=True, fill_value=np.int16(-32768), + zlib=True, fill_value=default_fillvals['i2'], chunksizes=(1, nrow, ncol)) value.scale_factor = np.float64(map_value.scale_factor) value.add_offset = np.float64(map_value.add_offset) From 9d710969007f17531b0b56835f7bdb5afd0dca64 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Fri, 17 Jul 2026 12:49:36 +0200 Subject: [PATCH 13/36] Update fill values --- src/lisflood/global_modules/netcdf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lisflood/global_modules/netcdf.py b/src/lisflood/global_modules/netcdf.py index 49017409..df544a69 100644 --- a/src/lisflood/global_modules/netcdf.py +++ b/src/lisflood/global_modules/netcdf.py @@ -581,7 +581,7 @@ def write_netcdf_header(settings, and getattr(map_value, 'add_offset', None) is not None) if packing_enabled and has_packing: value = nf1.createVariable(var_name, 'i2', ('time', dim_lat_y, dim_lon_x), - zlib=True, fill_value=np.int16(-32768), + zlib=True, fill_value=default_fillvals['i2'], chunksizes=(1, nrow, ncol)) value.scale_factor = np.float64(map_value.scale_factor) value.add_offset = np.float64(map_value.add_offset) From ac75a1ae53dc179afdfc58f3d523cf86ae14e222 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Mon, 27 Jul 2026 18:21:21 +0200 Subject: [PATCH 14/36] adding Aggregation Functions --- .../global_modules/default_options.py | 2 +- src/lisflood/global_modules/output.py | 97 ++++++++++++++++++- src/lisfloodSettings_reference.xml | 48 ++++++++- 3 files changed, 143 insertions(+), 4 deletions(-) diff --git a/src/lisflood/global_modules/default_options.py b/src/lisflood/global_modules/default_options.py index a10fa039..8d21928b 100644 --- a/src/lisflood/global_modules/default_options.py +++ b/src/lisflood/global_modules/default_options.py @@ -2,7 +2,7 @@ TimeSeries = namedtuple('TimeSeries', 'name, output_var, where, repoption, restrictoption, operation') ReportedMap = namedtuple('ReportedMap', 'name, output_var, unit, end, steps, all, restrictoption, monthly, yearly, scale_factor, add_offset') -ReportedMap.__new__.__defaults__ = (None, None) # sets scale and offset per default to None and as optionally +ReportedMap.__new__.__defaults__ = (None, None) # scale_factor, add_offset default_options = {'EnKF': False, 'InitLisflood': False, diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index 14687989..56f89f07 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -413,6 +413,72 @@ def _start_date(self): def _rep_steps(self): return self._rep_steps_val + +class MapOutputAggregated(MapOutput): + """Handles temporal aggregation (monthly/yearly mean/sum) for a variable.""" + + def __init__(self, var, map_key, map_value, frequency, operation): + out_type = 'all' # accumulates every timestep + settings = LisSettings.instance() + binding = settings.binding + self._start_date_val = var.CalendarDayStart + self._rep_steps_val = range(binding['StepStartInt'], binding['StepEndInt'] + 1) + + self._operation = operation # 'mean' or 'sum' + self._accum_buffer = None + self._accum_count = 0 + + super().__init__(var, out_type, frequency, map_key, map_value) + + # Force immediate write for aggregated outputs (one slice per period) + if hasattr(self, 'writer') and hasattr(self.writer, 'chunks'): + self.writer.chunks = 1 + + def _output_checkpoint(self): + """Always True — we accumulate every timestep.""" + return True + + @property + def _start_date(self): + return self._start_date_val + + @property + def _rep_steps(self): + return self._rep_steps_val + + def stage(self): + """Accumulate instead of storing instantaneous values.""" + self.step = self.var.currentTimeStep() + map_np = self.writer._extract_map() + + if self._accum_buffer is None: + self._accum_buffer = np.zeros_like(map_np) + + self._accum_buffer += map_np + self._accum_count += 1 + + def write(self): + """Write only at period boundary (month-end or year-end).""" + cdfflags = CDFFlags.instance() + is_boundary = cdfflags.frequency_check(self.var, self.frequency) + + if is_boundary and self._accum_buffer is not None: + # Finalize + if self._operation == 'mean': + result = self._accum_buffer / self._accum_count + else: # sum + result = self._accum_buffer + + # Stage the aggregated result into the writer + self.writer.data_steps.append(result) + cdf = CDFFlags.instance() + self.writer.step_range.append(cdf[self.writer.flag]) + self.writer.write(self._start_date, self._rep_steps) + + # Reset accumulator + self._accum_buffer = None + self._accum_count = 0 + # ------------------------------------------------------------------------ # Output factory # ------------------------------------------------------------------------ @@ -460,11 +526,38 @@ def __init__(self, var): if out.is_valid(): outputs.append(out) - check_duplicates = [] + # --- Temporal aggregation outputs --- + binding = settings.binding + aggregation_configs = { + 'OutputMonthlyMean': ('monthly', 'mean'), + 'OutputMonthlySum': ('monthly', 'sum'), + 'OutputYearlyMean': ('yearly', 'mean'), + 'OutputYearlySum': ('yearly', 'sum'), + } + aggregated_vars = set() # track which vars are aggregated + + reportedmaps = settings.options['reportedmaps'] + for setting_key, (frequency, operation) in aggregation_configs.items(): + var_list = binding.get(setting_key, '').split(';') + for var_name in var_list: + var_name = var_name.strip() + if var_name and var_name in reportedmaps: + map_value = reportedmaps[var_name] + out = MapOutputAggregated(var, var_name, map_value, frequency, operation) + if out.is_valid(): + outputs.append(out) + aggregated_vars.add(var_name) + + # Remove normal outputs for variables that are now aggregated outputs_clean = [] + check_duplicates = [] for out in outputs: + # Skip normal Maps/All output if variable is aggregated + if hasattr(out, 'map_key') and out.map_key in aggregated_vars: + if not isinstance(out, (MapOutputEnd, MapOutputAggregated)): + continue if out.map_path in check_duplicates: - print(f'Warning! Output map {out.map_path} is duplicated, check list of outputs') + print(f'Warning! Output map {out.map_path} is duplicated') else: check_duplicates.append(out.map_path) outputs_clean.append(out) diff --git a/src/lisfloodSettings_reference.xml b/src/lisfloodSettings_reference.xml index 3798b659..d17757e8 100644 --- a/src/lisfloodSettings_reference.xml +++ b/src/lisfloodSettings_reference.xml @@ -355,6 +355,33 @@ You can use builtin path variables in this template and reference to other paths + + + Semicolon-separated list of variable names to output as monthly mean. + Variables listed here are excluded from normal ReportSteps output. + Example: "DischargeMaps;Theta1Maps;UZMaps" + Leave empty to disable. + + + + + + See OutputMonthlyMean + + + + + + See OutputMonthlyMean + + + + + + See OutputMonthlyMean + + + @@ -1926,7 +1953,26 @@ You can use builtin path variables in this template and reference to other paths Number of days used for internal spin-up (fluxes computations during prerun) - + + + + Semicolon-separated list of variable names to output as monthly mean. + Variables listed here are excluded from normal ReportSteps output. + Example: "DischargeMaps;Theta1Maps;UZMaps" + Leave empty to disable. + + + + See OutputMonthlyMean + + + + See OutputMonthlyMean + + + + See OutputMonthlyMean + From f88b4ce271a0a194d2361739cc27bf1f4a0db0c2 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 28 Jul 2026 10:05:47 +0200 Subject: [PATCH 15/36] Update settings.xml --- src/lisfloodSettings_reference.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lisfloodSettings_reference.xml b/src/lisfloodSettings_reference.xml index d17757e8..c2356475 100644 --- a/src/lisfloodSettings_reference.xml +++ b/src/lisfloodSettings_reference.xml @@ -1961,18 +1961,26 @@ You can use builtin path variables in this template and reference to other paths Example: "DischargeMaps;Theta1Maps;UZMaps" Leave empty to disable. + + See OutputMonthlyMean + + See OutputMonthlyMean + + See OutputMonthlyMean + + From 8d9566d4ce795429683550aeeb594f14d3d42f55 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 28 Jul 2026 10:13:37 +0200 Subject: [PATCH 16/36] Update settings.xml --- src/lisfloodSettings_reference.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lisfloodSettings_reference.xml b/src/lisfloodSettings_reference.xml index c2356475..666d042d 100644 --- a/src/lisfloodSettings_reference.xml +++ b/src/lisfloodSettings_reference.xml @@ -364,19 +364,19 @@ You can use builtin path variables in this template and reference to other paths - + See OutputMonthlyMean - + See OutputMonthlyMean - + See OutputMonthlyMean @@ -1954,28 +1954,28 @@ You can use builtin path variables in this template and reference to other paths - + Semicolon-separated list of variable names to output as monthly mean. Variables listed here are excluded from normal ReportSteps output. Example: "DischargeMaps;Theta1Maps;UZMaps" Leave empty to disable. - - + + See OutputMonthlyMean - + See OutputMonthlyMean - + See OutputMonthlyMean From 5882f241a02c528c9117e7b85cfec7ab8ffdfe68 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 28 Jul 2026 12:41:00 +0200 Subject: [PATCH 17/36] Update --- src/lisflood/global_modules/settings.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/lisflood/global_modules/settings.py b/src/lisflood/global_modules/settings.py index d60a93bd..ef47361f 100755 --- a/src/lisflood/global_modules/settings.py +++ b/src/lisflood/global_modules/settings.py @@ -841,6 +841,15 @@ def __init__(self, model): msg += "\t[X] The simulation output as specified in the settings file can be found in {}\n".format(out_dir) msg += "\t[X] Activated modules: {}\n".format(activated_options) msg += "\t[X] Report options: {}\n".format(activated_rep) + msg += "\t[X] Activated modules: {}\n".format(activated_options) + msg += "\t[X] Report options: {}\n".format(activated_rep) + # Packing and aggregation info + if binding.get('OutputPacking', 'False') == 'True': + msg += "\t[X] Output Packing: int16 scale/offset enabled\n" + for agg_key in ['OutputMonthlyMean', 'OutputMonthlySum', 'OutputYearlyMean', 'OutputYearlySum']: + agg_val = binding.get(agg_key, '').strip() + if agg_val: + msg += "\t[X] {}: {}\n".format(agg_key, agg_val) self._msg = '{}{}'.format(header, msg) def __str__(self): From 9f916c4a32075d67aaf2d6d6423f7295956501be Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 28 Jul 2026 12:47:38 +0200 Subject: [PATCH 18/36] Debug Statement --- src/lisflood/global_modules/output.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index 56f89f07..f3448277 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -547,6 +547,7 @@ def __init__(self, var): if out.is_valid(): outputs.append(out) aggregated_vars.add(var_name) + print(f"DEBUG aggregated_vars: {aggregated_vars}") # Remove normal outputs for variables that are now aggregated outputs_clean = [] From 9dc1da9a6950c517e70f717c493d57fcfcba32ae Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 28 Jul 2026 12:52:50 +0200 Subject: [PATCH 19/36] Debug Statement --- src/lisflood/global_modules/settings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lisflood/global_modules/settings.py b/src/lisflood/global_modules/settings.py index ef47361f..2dac5c71 100755 --- a/src/lisflood/global_modules/settings.py +++ b/src/lisflood/global_modules/settings.py @@ -844,6 +844,7 @@ def __init__(self, model): msg += "\t[X] Activated modules: {}\n".format(activated_options) msg += "\t[X] Report options: {}\n".format(activated_rep) # Packing and aggregation info + binding = settings.binding if binding.get('OutputPacking', 'False') == 'True': msg += "\t[X] Output Packing: int16 scale/offset enabled\n" for agg_key in ['OutputMonthlyMean', 'OutputMonthlySum', 'OutputYearlyMean', 'OutputYearlySum']: From 3580718b69024543a1fd7bd55c5152a674d1416c Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 28 Jul 2026 14:33:32 +0200 Subject: [PATCH 20/36] Debug Statement --- src/lisflood/global_modules/output.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index f3448277..87fd3a70 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -547,7 +547,6 @@ def __init__(self, var): if out.is_valid(): outputs.append(out) aggregated_vars.add(var_name) - print(f"DEBUG aggregated_vars: {aggregated_vars}") # Remove normal outputs for variables that are now aggregated outputs_clean = [] @@ -556,6 +555,7 @@ def __init__(self, var): # Skip normal Maps/All output if variable is aggregated if hasattr(out, 'map_key') and out.map_key in aggregated_vars: if not isinstance(out, (MapOutputEnd, MapOutputAggregated)): + print(f"DEBUG EXCLUDING: {out.map_key} (type={type(out).__name__})") continue if out.map_path in check_duplicates: print(f'Warning! Output map {out.map_path} is duplicated') From 0af2e47da551e8e4803b0f28a380b7fe710ab58f Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 28 Jul 2026 14:35:37 +0200 Subject: [PATCH 21/36] Debug Statement --- src/lisflood/global_modules/settings.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/lisflood/global_modules/settings.py b/src/lisflood/global_modules/settings.py index 2dac5c71..8285407f 100755 --- a/src/lisflood/global_modules/settings.py +++ b/src/lisflood/global_modules/settings.py @@ -841,8 +841,6 @@ def __init__(self, model): msg += "\t[X] The simulation output as specified in the settings file can be found in {}\n".format(out_dir) msg += "\t[X] Activated modules: {}\n".format(activated_options) msg += "\t[X] Report options: {}\n".format(activated_rep) - msg += "\t[X] Activated modules: {}\n".format(activated_options) - msg += "\t[X] Report options: {}\n".format(activated_rep) # Packing and aggregation info binding = settings.binding if binding.get('OutputPacking', 'False') == 'True': From 6a608ee0157f82c3fc39abe90cbf485a2d7245f3 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 28 Jul 2026 14:48:43 +0200 Subject: [PATCH 22/36] Debug Statement --- src/lisflood/global_modules/output.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index 87fd3a70..34b62b5c 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -417,6 +417,11 @@ def _rep_steps(self): class MapOutputAggregated(MapOutput): """Handles temporal aggregation (monthly/yearly mean/sum) for a variable.""" + def write(self): + cdfflags = CDFFlags.instance() + is_boundary = cdfflags.frequency_check(self.var, self.frequency) + print(f"AGG WRITE CHECK: step={self.var.currentTimeStep()}, is_boundary={is_boundary}, accum_count={self._accum_count}, buffer_exists={self._accum_buffer is not None}") + def __init__(self, var, map_key, map_value, frequency, operation): out_type = 'all' # accumulates every timestep settings = LisSettings.instance() @@ -555,7 +560,6 @@ def __init__(self, var): # Skip normal Maps/All output if variable is aggregated if hasattr(out, 'map_key') and out.map_key in aggregated_vars: if not isinstance(out, (MapOutputEnd, MapOutputAggregated)): - print(f"DEBUG EXCLUDING: {out.map_key} (type={type(out).__name__})") continue if out.map_path in check_duplicates: print(f'Warning! Output map {out.map_path} is duplicated') From b8d835bc63d37f965b61174987bb0d54e4806b0e Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 28 Jul 2026 15:04:00 +0200 Subject: [PATCH 23/36] Debug Statement --- src/lisflood/global_modules/output.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index 34b62b5c..cabfee7b 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -568,6 +568,7 @@ def __init__(self, var): outputs_clean.append(out) self.output_maps = outputs_clean + print(f"DEBUG FINAL outputs: {[(type(o).__name__, getattr(o, 'map_key', '?')) for o in self.output_maps]}") def write(self): # synchronous approach, no real need to stage and then write From 4969862f4a0b6659fd49b1e7fc417f704459ab97 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 28 Jul 2026 15:08:23 +0200 Subject: [PATCH 24/36] Debug Statement --- src/lisflood/global_modules/output.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index cabfee7b..49a2bd2a 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -417,11 +417,6 @@ def _rep_steps(self): class MapOutputAggregated(MapOutput): """Handles temporal aggregation (monthly/yearly mean/sum) for a variable.""" - def write(self): - cdfflags = CDFFlags.instance() - is_boundary = cdfflags.frequency_check(self.var, self.frequency) - print(f"AGG WRITE CHECK: step={self.var.currentTimeStep()}, is_boundary={is_boundary}, accum_count={self._accum_count}, buffer_exists={self._accum_buffer is not None}") - def __init__(self, var, map_key, map_value, frequency, operation): out_type = 'all' # accumulates every timestep settings = LisSettings.instance() @@ -466,6 +461,7 @@ def write(self): """Write only at period boundary (month-end or year-end).""" cdfflags = CDFFlags.instance() is_boundary = cdfflags.frequency_check(self.var, self.frequency) + print(f"AGG WRITE CHECK: step={self.var.currentTimeStep()}, is_boundary={is_boundary}, accum_count={self._accum_count}, buffer_exists={self._accum_buffer is not None}") if is_boundary and self._accum_buffer is not None: # Finalize From ac359c3bcd4443e4e85496f3c711e41a65322f77 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 28 Jul 2026 15:20:16 +0200 Subject: [PATCH 25/36] Update Debug --- src/lisflood/global_modules/output.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index 49a2bd2a..1e335bf0 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -15,6 +15,7 @@ """ import os +import datetime import numpy as np from pcraster import ifthen, catchmenttotal, mapmaximum import sys @@ -427,6 +428,7 @@ def __init__(self, var, map_key, map_value, frequency, operation): self._operation = operation # 'mean' or 'sum' self._accum_buffer = None self._accum_count = 0 + self._write_step = 0 # own step counter for NetCDF time dimension super().__init__(var, out_type, frequency, map_key, map_value) @@ -459,9 +461,14 @@ def stage(self): def write(self): """Write only at period boundary (month-end or year-end).""" - cdfflags = CDFFlags.instance() - is_boundary = cdfflags.frequency_check(self.var, self.frequency) - print(f"AGG WRITE CHECK: step={self.var.currentTimeStep()}, is_boundary={is_boundary}, accum_count={self._accum_count}, buffer_exists={self._accum_buffer is not None}") + current_date = self.var.CalendarDate + next_date = current_date + datetime.timedelta(days=self.var.DtDay) + if self.frequency == 'monthly': + is_boundary = current_date.month != next_date.month + elif self.frequency == 'yearly': + is_boundary = current_date.year != next_date.year + else: + is_boundary = True if is_boundary and self._accum_buffer is not None: # Finalize @@ -472,11 +479,11 @@ def write(self): # Stage the aggregated result into the writer self.writer.data_steps.append(result) - cdf = CDFFlags.instance() - self.writer.step_range.append(cdf[self.writer.flag]) + self.writer.step_range.append(self._write_step) self.writer.write(self._start_date, self._rep_steps) - # Reset accumulator + # Increment own step counter and reset accumulator + self._write_step += 1 self._accum_buffer = None self._accum_count = 0 @@ -564,7 +571,6 @@ def __init__(self, var): outputs_clean.append(out) self.output_maps = outputs_clean - print(f"DEBUG FINAL outputs: {[(type(o).__name__, getattr(o, 'map_key', '?')) for o in self.output_maps]}") def write(self): # synchronous approach, no real need to stage and then write From f0e69714c081a0aaecdc57f66280c7148eb8d64b Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 28 Jul 2026 15:34:15 +0200 Subject: [PATCH 26/36] Update Debug --- src/lisflood/global_modules/output.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index 1e335bf0..2ae8daeb 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -430,7 +430,11 @@ def __init__(self, var, map_key, map_value, frequency, operation): self._accum_count = 0 self._write_step = 0 # own step counter for NetCDF time dimension - super().__init__(var, out_type, frequency, map_key, map_value) + # Disable int16 packing for aggregated outputs — scale/offset ranges + # are calibrated for daily values and don't apply to monthly/yearly aggregates + map_value_no_pack = map_value._replace(scale_factor=None, add_offset=None) + + super().__init__(var, out_type, frequency, map_key, map_value_no_pack) # Force immediate write for aggregated outputs (one slice per period) if hasattr(self, 'writer') and hasattr(self.writer, 'chunks'): From 3098d635eca1f7f948679fc07f592dd95c61eef2 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Wed, 29 Jul 2026 12:09:59 +0200 Subject: [PATCH 27/36] Remove discharge output packing due to precision --- src/lisflood/global_modules/default_options.py | 3 +-- src/lisfloodSettings_reference.xml | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/lisflood/global_modules/default_options.py b/src/lisflood/global_modules/default_options.py index 8d21928b..fa426853 100644 --- a/src/lisflood/global_modules/default_options.py +++ b/src/lisflood/global_modules/default_options.py @@ -360,8 +360,7 @@ 'DischargeMaps': ReportedMap(name='DischargeMaps', output_var='ChanQAvg', unit='m3/s', end=[], steps=[], all=['repDischargeMaps'], restrictoption=[], - monthly=False, yearly=False, - scale_factor=6.104, add_offset=200000.0), + monthly=False, yearly=False), 'EFlowIndicator': ReportedMap(name='EFlowIndicator', output_var='EFlowIndicator', unit='-', end=[], steps=['repTotalAbs'], all=[], restrictoption=['nonInit', 'wateruse', diff --git a/src/lisfloodSettings_reference.xml b/src/lisfloodSettings_reference.xml index 666d042d..0746f45e 100644 --- a/src/lisfloodSettings_reference.xml +++ b/src/lisfloodSettings_reference.xml @@ -1962,7 +1962,7 @@ You can use builtin path variables in this template and reference to other paths Leave empty to disable. - + See OutputMonthlyMean @@ -5226,8 +5226,8 @@ You can use builtin path variables in this template and reference to other paths ************************************************************** TABLES WITH TOPSOIL SOIL PHYSICAL PARAMETERS (HYPRES) - Each parameter is defined for upper (1a and 1b) and - lower (2) soil layers + Each parameter is defined for upper (1 and 2) and + lower (3) soil layers ************************************************************** @@ -5331,7 +5331,7 @@ You can use builtin path variables in this template and reference to other paths ************************************************************** TABLES WITH TOPSOIL SOIL PHYSICAL PARAMETERS (HYPRES) for Forest - Each parameter is defined for 1a and 1b + Each parameter is defined for 1 and 2 Normal parameter is taken for the lower soil layer ************************************************************** From f31f67f34278bee4be929f9a370c7ecd6fe0506f Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Wed, 29 Jul 2026 15:53:18 +0200 Subject: [PATCH 28/36] Fix non nan masking outside the basin mask when aggregating outputs --- src/lisflood/global_modules/output.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index 2ae8daeb..a45d4a95 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -166,7 +166,6 @@ def write(self, start_date, rep_steps): nf1 = iterOpenNetcdf(self.map_path, "", 'a', format='NETCDF4') nc_var = nf1.variables[self.map_name] - nc_var.set_auto_maskandscale(False) is_packed = nc_var.dtype == np.int16 if is_packed: nc_var.set_auto_maskandscale(False) From c22201eaccd22e516ac2c34063a57f9af3f4d980 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 4 Aug 2026 10:07:47 +0200 Subject: [PATCH 29/36] Implement Carlos Comments --- src/lisflood/global_modules/default_options.py | 2 +- src/lisflood/global_modules/netcdf.py | 17 ++++++++++------- src/lisflood/global_modules/output.py | 10 +++++++--- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/lisflood/global_modules/default_options.py b/src/lisflood/global_modules/default_options.py index fa426853..77860df3 100644 --- a/src/lisflood/global_modules/default_options.py +++ b/src/lisflood/global_modules/default_options.py @@ -352,7 +352,7 @@ output_var='DirectRunoff', unit='mm', end=[], steps=['repSurfaceRunoffMaps'], all=[''], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.006104, add_offset=200.0), + yearly=False, scale_factor=0.0061, add_offset=200.0), 'DischargeEnd': ReportedMap(name='DischargeEnd', output_var='ChanQAvg', unit='m3/s', end=[], steps=[], all=[], restrictoption=[], monthly=False, diff --git a/src/lisflood/global_modules/netcdf.py b/src/lisflood/global_modules/netcdf.py index df544a69..e890bd35 100644 --- a/src/lisflood/global_modules/netcdf.py +++ b/src/lisflood/global_modules/netcdf.py @@ -574,20 +574,23 @@ def write_netcdf_header(settings, nf1.variables["time"][:] = date2num(time_stamps, time.units, time.calendar) # value = nf1.createVariable(var_name, dtype, ('time', dim_lat_y, dim_lon_x), zlib=True, fill_value=-9999, chunksizes=(1, nrow, ncol)) - # NEW packing: + # Packing: use int16 with CF scale/offset if enabled and variable has packing metadata packing_enabled = binding.get('OutputPacking', 'False') == 'True' has_packing = (map_value is not None and getattr(map_value, 'scale_factor', None) is not None and getattr(map_value, 'add_offset', None) is not None) if packing_enabled and has_packing: - value = nf1.createVariable(var_name, 'i2', ('time', dim_lat_y, dim_lon_x), - zlib=True, fill_value=default_fillvals['i2'], - chunksizes=(1, nrow, ncol)) + var_dtype = 'i2' + var_fill = default_fillvals['i2'] + else: + var_dtype = dtype + var_fill = -9999 + + value = nf1.createVariable(var_name, var_dtype, ('time', dim_lat_y, dim_lon_x), + zlib=True, fill_value=var_fill, chunksizes=(1, nrow, ncol)) + if packing_enabled and has_packing: value.scale_factor = np.float64(map_value.scale_factor) value.add_offset = np.float64(map_value.add_offset) - else: - value = nf1.createVariable(var_name, dtype, ('time', dim_lat_y, dim_lon_x), - zlib=True, fill_value=-9999, chunksizes=(1, nrow, ncol)) else: value = nf1.createVariable(var_name, dtype, (dim_lat_y, dim_lon_x), zlib=True, fill_value=-9999) diff --git a/src/lisflood/global_modules/output.py b/src/lisflood/global_modules/output.py index a45d4a95..47640371 100644 --- a/src/lisflood/global_modules/output.py +++ b/src/lisflood/global_modules/output.py @@ -429,9 +429,13 @@ def __init__(self, var, map_key, map_value, frequency, operation): self._accum_count = 0 self._write_step = 0 # own step counter for NetCDF time dimension - # Disable int16 packing for aggregated outputs — scale/offset ranges - # are calibrated for daily values and don't apply to monthly/yearly aggregates - map_value_no_pack = map_value._replace(scale_factor=None, add_offset=None) + # Disable int16 packing for sum aggregates — monthly/yearly sums can exceed + # the int16 range calibrated for daily values. Mean aggregates stay within + # the same value range as daily output, so packing remains valid. + if operation == 'sum': + map_value_no_pack = map_value._replace(scale_factor=None, add_offset=None) + else: + map_value_no_pack = map_value super().__init__(var, out_type, frequency, map_key, map_value_no_pack) From cd2c9f270f8b3a7e27fa6074b8035700ff1d4af8 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Tue, 4 Aug 2026 14:31:55 +0200 Subject: [PATCH 30/36] Rounding some scale factors --- .../global_modules/default_options.py | 100 +++++++++--------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/src/lisflood/global_modules/default_options.py b/src/lisflood/global_modules/default_options.py index 77860df3..13b85247 100644 --- a/src/lisflood/global_modules/default_options.py +++ b/src/lisflood/global_modules/default_options.py @@ -352,7 +352,7 @@ output_var='DirectRunoff', unit='mm', end=[], steps=['repSurfaceRunoffMaps'], all=[''], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.0061, add_offset=200.0), + yearly=False, scale_factor=0.006, add_offset=200.0), 'DischargeEnd': ReportedMap(name='DischargeEnd', output_var='ChanQAvg', unit='m3/s', end=[], steps=[], all=[], restrictoption=[], monthly=False, @@ -369,46 +369,46 @@ 'ESActForestMaps': ReportedMap(name='ESActForestMaps', output_var='ESAct[1]', unit='mm', end=[], steps=[''], all=['repESActMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False,scale_factor=3.052e-4, add_offset=10.), + monthly=False, yearly=False,scale_factor=3.05e-4, add_offset=10.), 'ESActMaps': ReportedMap(name='ESActMaps', output_var='ESActPixel', unit='mm', end=[], steps=[], all=['repESActMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=3.052e-4, add_offset=10.0), + scale_factor=3.05e-4, add_offset=10.0), 'ESRefMapsOut': ReportedMap(name='ESRefMapsOut', output_var='ESRef', unit='mm', end=[], steps=[], all=['repESRefMaps'], restrictoption=[], monthly=False, yearly=False, - scale_factor=3.052e-4, add_offset=10.0), + scale_factor=3.05e-4, add_offset=10.0), 'ETActMaps': ReportedMap(name='ETActMaps', output_var='ESActPixel+self.var.TaPixel+self.var.TaInterceptionAll+self.var.EvaAddM3*self.var.M3toMM', unit='mm', end=[], steps=[], all=['repETActMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=0.01541, add_offset=495.0), + scale_factor=0.0154, add_offset=495.0), 'ETActBudykoMaps': ReportedMap(name='ETActBudykoMaps', output_var='ESActNoIrrPixel+self.var.TaNoIrrPixel+self.var.TaInterceptionNoIrrPixel', unit='mm', end=[], steps=[], all=['repETActMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=0.01541, add_offset=495.0), + scale_factor=0.0154, add_offset=495.0), 'ETRefMapsOut': ReportedMap(name='ETRefMapsOut', output_var='ETRef', unit='mm', end=[], steps=[], all=['repETRefMaps'], restrictoption=[], monthly=False, yearly=False, - scale_factor=3.052e-4, add_offset=10.0), + scale_factor=3.05e-4, add_offset=10.0), 'EWIntForestMaps': ReportedMap(name='EWIntForestMaps', output_var='TaInterception[1]', unit='mm', end=[], steps=[], all=['repEWIntMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=3.052e-4, add_offset=10.0), + yearly=False, scale_factor=3.05e-4, add_offset=10.0), 'EWIntMaps': ReportedMap(name='EWIntMaps', output_var='TaInterceptionAll', unit='mm', end=[], steps=[], all=['repEWIntMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=3.052e-4, add_offset=10.0), + scale_factor=3.05e-4, add_offset=10.0), 'EWRefMapsOut': ReportedMap(name='EWRefMapsOut', output_var='EWRef', unit='mm', end=[], steps=[], all=['repEWRefMaps'], restrictoption=[], monthly=False, yearly=False, - scale_factor=3.052e-4, add_offset=10.0), + scale_factor=3.05e-4, add_offset=10.0), 'EWater': ReportedMap(name='EWater', output_var='EvaAddM3*self.var.M3toMM', unit='mm', end=[], steps=[], all=['repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=3.052e-4, add_offset=10.0), + scale_factor=3.05e-4, add_offset=10.0), 'FalkenmarkM3Capita1': ReportedMap(name='FalkenmarkM3Capita1', output_var='FalkenmarkM3Capita1', unit='M3Capita', end=[], @@ -435,7 +435,7 @@ output_var='SurfaceRunoff+self.var.UZOutflowPixel', unit='mm', end=[], steps=[], all=['repFastRunoffMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.007630, add_offset=250), + yearly=False, scale_factor=0.0076, add_offset=250), 'FossilGroundwaterUsedM3': ReportedMap(name='FossilGroundwaterUsedM3', output_var='FossilGroundwaterUsedM3', unit='m3', end=[], @@ -469,49 +469,49 @@ end=[], steps=['repGwPercUZLZMaps'], all=['repGwPercUZLZMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.578e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-5, add_offset=1.5), 'GwPercUZLZIrrigationMaps': ReportedMap(name='GwPercUZLZForestMaps', output_var='GwPercUZLZ[2]', unit='mm', end=[], steps=['repGwPercUZLZMaps'], all=['repGwPercUZLZMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.578e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-5, add_offset=1.5), 'GwPercUZLZOtherMaps': ReportedMap(name='GwPercUZLZForestMaps', output_var='GwPercUZLZ[0]', unit='mm', end=[], steps=[], all=['repGwPercUZLZMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.578e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-5, add_offset=1.5), 'GwPercUZLZMaps': ReportedMap(name='GwPercUZLZMaps', output_var='GwPercUZLZPixel', unit='mm', end=[], steps=[], all=['repGwPercUZLZMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.578e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-5, add_offset=1.5), 'InfiltrationForestMaps': ReportedMap(name='InfiltrationForestMaps', output_var='Infiltration[1]', unit='mm', end=[], steps=[], all=['repInfiltrationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.007630, add_offset=250.), + yearly=False, scale_factor=0.0076, add_offset=250.), 'InfiltrationMaps': ReportedMap(name='InfiltrationMaps', output_var='Infiltration[0]', unit='mm', end=[], steps=[], all=['repInfiltrationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.007630, add_offset=250.), + yearly=False, scale_factor=0.0076, add_offset=250.), 'InterceptionForestMaps': ReportedMap(name='InterceptionForestMaps', output_var='Interception[1]', unit='mm', end=[], steps=[], all=['repInterceptionMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=2.289e-4, add_offset=7.5), + yearly=False, scale_factor=2.3e-4, add_offset=7.5), 'InterceptionMaps': ReportedMap(name='InterceptionMaps', output_var='Interception[0]', unit='mm', end=[], steps=[], all=['repInterceptionMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=2.289e-4, add_offset=7.5), + yearly=False, scale_factor=2.3e-4, add_offset=7.5), 'LocalFreshwaterM3': ReportedMap(name='LocalFreshwaterM3', output_var='LocalFreshwaterM3', unit='m3', end=[], @@ -707,34 +707,34 @@ output_var='SeepTopToSubA[0]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.578e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-5, add_offset=1.5), 'Percolation1ato1bForestMaps': ReportedMap(name='Percolation1ato1bForestMaps', output_var='SeepTopToSubA[1]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.578e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-5, add_offset=1.5), 'Percolation1ato1bIrrigationMaps': ReportedMap(name='Percolation1ato1bIrrigationMaps', output_var='SeepTopToSubA[2]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.578e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-5, add_offset=1.5), 'Percolation1bto2OtherMaps': ReportedMap(name='Percolation1bto2OtherMaps', output_var='SeepTopToSubB[0]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.578e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-5, add_offset=1.5), 'Percolation1bto2ForestMaps': ReportedMap(name='Percolation1bto2ForestMaps', output_var='SeepTopToSubB[1]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.578e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-5, add_offset=1.5), 'Percolation1bto2IrrigationMaps': ReportedMap(name='Percolation1bto2IrrigationMaps', output_var='SeepTopToSubB[2]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.578e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-5, add_offset=1.5), 'PrevCmMCTEnd': ReportedMap(name='PrevCmMCTEnd', output_var='PrevCm0', unit='-', end=['repEndMaps'], steps=[], all=[], restrictoption=['nonInit','MCTRouting'], monthly=False, yearly=False), @@ -978,22 +978,22 @@ end=[], steps=[], all=['repSurfaceRunoffMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.007630, add_offset=250.), + yearly=False, scale_factor=0.0076, add_offset=250.), 'TaOtherMaps': ReportedMap(name='TaOtherMaps', output_var='Ta[0]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=2.289e-4, add_offset=7.5), + yearly=False, scale_factor=2.3e-4, add_offset=7.5), 'TaForestMaps': ReportedMap(name='TaForestMaps', output_var='Ta[1]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=2.289e-4, add_offset=7.5), + yearly=False, scale_factor=2.3e-4, add_offset=7.5), 'TaIrrigationMaps': ReportedMap(name='TaIrrigationMaps', output_var='Ta[2]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=2.289e-4, add_offset=7.5), + yearly=False, scale_factor=2.3e-4, add_offset=7.5), 'TaMaps': ReportedMap(name='TaMaps', output_var='TaPixel', unit='mm', end=[], steps=[], all=['repE2O1','repTaMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=2.289e-4, add_offset=7.5), + monthly=False, yearly=False, scale_factor=2.3e-4, add_offset=7.5), 'TavgMapsOut': ReportedMap(name='TavgMapsOut', output_var='Tavg', unit='degree', end=[], steps=[], all=['repTavgMaps'], restrictoption=[], monthly=False, yearly=False), @@ -1008,12 +1008,12 @@ unit='', end=[], steps=[], all=['repThetaForestMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta1ForestState': ReportedMap(name='Theta1ForestState', output_var='Theta1a[1]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta1IrrigationEnd': ReportedMap(name='Theta1IrrigationEnd', output_var='Theta1a[2]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], @@ -1024,20 +1024,20 @@ end=[], steps=[], all=['repThetaIrrigationMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta1IrrigationState': ReportedMap(name='Theta1IrrigationState', output_var='Theta1a[2]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta1Maps': ReportedMap(name='Theta1Maps', output_var='Theta1a[0]', unit='', end=[], steps=[], all=['repThetaMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta1State': ReportedMap(name='Theta1State', output_var='Theta1a[0]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta2End': ReportedMap(name='Theta2End', output_var='Theta1b[0]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, yearly=False), @@ -1049,12 +1049,12 @@ unit='', end=[], steps=[], all=['repThetaForestMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta2ForestState': ReportedMap(name='Theta2ForestState', output_var='Theta1b[1]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta2IrrigationEnd': ReportedMap(name='Theta2IrrigationEnd', output_var='Theta1b[2]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], @@ -1065,20 +1065,20 @@ end=[], steps=[], all=['repThetaIrrigationMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta2IrrigationState': ReportedMap(name='Theta2IrrigationState', output_var='Theta1b[2]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta2Maps': ReportedMap(name='Theta2Maps', output_var='Theta1b[0]', unit='', end=[], steps=[], all=['repThetaMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta2State': ReportedMap(name='Theta2State', output_var='Theta1b[0]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta3End': ReportedMap(name='Theta3End', output_var='Theta2[0]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, yearly=False), @@ -1090,12 +1090,12 @@ unit='', end=[], steps=[], all=['repThetaForestMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta3ForestState': ReportedMap(name='Theta3ForestState', output_var='Theta2[1]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta3IrrigationEnd': ReportedMap(name='Theta3IrrigationEnd', output_var='Theta2[2]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], @@ -1105,20 +1105,20 @@ output_var='Theta2[2]', unit='', end=[], steps=[], all=['repThetaIrrigationMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta3IrrigationState': ReportedMap(name='Theta3IrrigationState', output_var='Theta2[2]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta3Maps': ReportedMap(name='Theta3Maps', output_var='Theta2[0]', unit='', end=[], steps=[], all=['repThetaMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'Theta3State': ReportedMap(name='Theta3State', output_var='Theta2[0]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.526e-5, add_offset=0.5), + yearly=False, scale_factor=1.53e-5, add_offset=0.5), 'TotalAbsGroundwater': ReportedMap(name='TotalAbsGroundwater', output_var='abstraction_GW_actual_M3*self.var.M3toMM', unit='mm', end=[], steps=['repTotalAbs'], @@ -1163,7 +1163,7 @@ output_var='TotalRunoff', unit='mm', end=[], steps=[], all=['repTotalRunoffMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=0.007630, add_offset=250.), + monthly=False, yearly=False, scale_factor=0.0076, add_offset=250.), 'TotalToChanMaps': ReportedMap(name='TotalToChanMaps', output_var='ToChanM3Runoff*self.var.M3toMM', unit='mm', end=[], steps=[], From cf98283b89cc427b2325b1bd463b2e0aeb4e4d03 Mon Sep 17 00:00:00 2001 From: doc78 Date: Tue, 4 Aug 2026 18:31:09 +0000 Subject: [PATCH 31/36] Added test for scale,offset and aggregation. Changed some scale values as test were failing for overflow --- .gitignore | 1 + .../global_modules/default_options.py | 10 +- tests/test_scale_offset_aggregation.py | 574 ++++++++++++++++++ 3 files changed, 580 insertions(+), 5 deletions(-) create mode 100644 tests/test_scale_offset_aggregation.py diff --git a/.gitignore b/.gitignore index 252b2998..3ec87b21 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.gem *.sublime-project *.sublime-workspace +.kiro .bundle .DS_Store .jekyll-metadata diff --git a/src/lisflood/global_modules/default_options.py b/src/lisflood/global_modules/default_options.py index 13b85247..ee7184db 100644 --- a/src/lisflood/global_modules/default_options.py +++ b/src/lisflood/global_modules/default_options.py @@ -539,7 +539,7 @@ restrictoption=[], monthly=False, yearly=False), 'LZMaps': ReportedMap(name='LZMaps', output_var='LZ', unit='mm', end=[], steps=[], all=['repLZMaps', 'repE2O2'], restrictoption=['nonInit'], - monthly=False, yearly=False,scale_factor=0.09156, add_offset=-1000.0), + monthly=False, yearly=False,scale_factor=0.2365, add_offset=7250.0), 'LZOutflowMaps': ReportedMap(name='LZOutflowMaps', output_var='LZOutflowToChannelPixel', unit='mm', end=[], steps=[], all=['repLZOutflowMaps','repE2O1'], @@ -982,18 +982,18 @@ 'TaOtherMaps': ReportedMap(name='TaOtherMaps', output_var='Ta[0]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=2.3e-4, add_offset=7.5), + yearly=False, scale_factor=3.815e-4, add_offset=2.5), 'TaForestMaps': ReportedMap(name='TaForestMaps', output_var='Ta[1]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=2.3e-4, add_offset=7.5), + yearly=False, scale_factor=3.815e-4, add_offset=2.5), 'TaIrrigationMaps': ReportedMap(name='TaIrrigationMaps', output_var='Ta[2]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=2.3e-4, add_offset=7.5), + yearly=False, scale_factor=3.815e-4, add_offset=2.5), 'TaMaps': ReportedMap(name='TaMaps', output_var='TaPixel', unit='mm', end=[], steps=[], all=['repE2O1','repTaMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=2.3e-4, add_offset=7.5), + monthly=False, yearly=False, scale_factor=3.815e-4, add_offset=2.5), 'TavgMapsOut': ReportedMap(name='TavgMapsOut', output_var='Tavg', unit='degree', end=[], steps=[], all=['repTavgMaps'], restrictoption=[], monthly=False, yearly=False), diff --git a/tests/test_scale_offset_aggregation.py b/tests/test_scale_offset_aggregation.py new file mode 100644 index 00000000..9e5b586d --- /dev/null +++ b/tests/test_scale_offset_aggregation.py @@ -0,0 +1,574 @@ +""" +Tests for the scale/offset packing and temporal aggregation features. + +These tests verify that: +1. Output maps produced with int16 scale/offset packing are equivalent to + float outputs within the expected quantization tolerance. +2. Aggregated (monthly mean/sum) outputs match the result of aggregating + the daily time-step outputs after the fact. +""" +from __future__ import absolute_import + +import os +import shutil +import datetime + +import numpy as np +import pytest +from netCDF4 import Dataset + +from lisflood.main import lisfloodexe +from lisflood.global_modules.default_options import default_options +from lisflood.global_modules.output import PACK_MIN, PACK_MAX + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + +def _find_data_var(ds): + """Find the main data variable in a netCDF4 Dataset (the 3D variable).""" + for name in ds.variables: + var = ds.variables[name] + if len(var.dimensions) == 3: + return name + # fallback: return first variable that is not a dimension or projection + dims = set(ds.dimensions.keys()) + skip = dims | {'laea', 'lambert_azimuthal_equal_area'} + for name in ds.variables: + if name not in skip: + return name + raise ValueError(f"No data variable found in {ds.filepath()}") + +def setoptions_with_new_vars(settings_file, opts_to_set=None, opts_to_unset=None, + vars_to_set=None, new_vars=None): + """Extended version of setoptions that can inject NEW textvar entries. + + Parameters + ---------- + settings_file : str + Path to XML settings template. + opts_to_set / opts_to_unset : list of str + Options to enable/disable. + vars_to_set : dict + Existing textvars to modify (name -> value). + new_vars : dict + New textvars to inject (name -> value). They are added to the first + section if not already present. + """ + import uuid + from bs4 import BeautifulSoup + from lxml import etree + from lisflood.global_modules.settings import LisSettings, Singleton + from lisflood.global_modules.errors import LisfloodError + + if isinstance(opts_to_set, str): + opts_to_set = [opts_to_set] + if isinstance(opts_to_unset, str): + opts_to_unset = [opts_to_unset] + + opts_to_set = [] if opts_to_set is None else opts_to_set + opts_to_unset = [] if opts_to_unset is None else opts_to_unset + vars_to_set = {} if vars_to_set is None else vars_to_set + new_vars = {} if new_vars is None else new_vars + + with open(settings_file) as filetocheck: + etree.parse(filetocheck) + + with open(settings_file) as tpl: + soup = BeautifulSoup(tpl, 'lxml-xml') + + # Set/unset options + lfoptions = soup.find('lfoptions') + for opt in opts_to_set: + tag = soup.find("setoption", {'name': opt}) + if tag: + tag['choice'] = '1' + elif lfoptions: + # Option not in XML — inject it + new_tag = soup.new_tag("setoption", attrs={'name': opt, 'choice': '1'}) + lfoptions.append(new_tag) + for opt in opts_to_unset: + tag = soup.find("setoption", {'name': opt}) + if tag: + tag['choice'] = '0' + elif lfoptions: + new_tag = soup.new_tag("setoption", attrs={'name': opt, 'choice': '0'}) + lfoptions.append(new_tag) + + # Modify existing textvars + for textvar, value in vars_to_set.items(): + for tag in soup.find_all("textvar", {'name': textvar}): + tag['value'] = value + break + + # Inject new textvars (add to both and sections) + if new_vars: + lfuser = soup.find('lfuser') + lfbinding = soup.find('lfbinding') + for name, value in new_vars.items(): + # Add/update in lfuser + if lfuser: + existing = lfuser.find("textvar", {'name': name}) + if existing: + existing['value'] = value + else: + new_tag = soup.new_tag("textvar", attrs={'name': name, 'value': value}) + lfuser.append(new_tag) + # Add/update in lfbinding (this is where the model reads bindings from) + if lfbinding: + existing = lfbinding.find("textvar", {'name': name}) + if existing: + existing['value'] = value + else: + new_tag = soup.new_tag("textvar", attrs={'name': name, 'value': value}) + lfbinding.append(new_tag) + + # Write temporary settings file + uid = uuid.uuid4() + filename = os.path.join(os.path.dirname(settings_file), + './{}_{}.xml'.format(os.path.basename(settings_file), uid)) + with open(filename, 'w') as dest: + dest.write(soup.prettify()) + try: + Singleton._instances = {} + Singleton._current = {} + settings = LisSettings(filename) + options = settings.options + for opt in opts_to_set: + options[opt] = True + for opt in opts_to_unset: + options[opt] = False + except LisfloodError as e: + raise e + finally: + os.unlink(filename) + return settings + + +def read_nc_variable(nc_path, var_name=None): + """Read the data variable from a NetCDF file. + + Returns + ------- + data : np.ndarray + The data array (auto-unscaled by netCDF4 library). Masked/fill values become NaN. + var_name : str + Name of the variable read. + """ + with Dataset(nc_path, 'r') as ds: + if var_name is None: + var_name = _find_data_var(ds) + var = ds.variables[var_name] + data = var[:] + # Convert masked arrays to float with NaN for masked/fill values + if hasattr(data, 'filled'): + data = data.filled(np.nan).astype(np.float64) + else: + data = np.array(data, dtype=np.float64) + # Also treat legacy -9999 fill values as NaN + data[data == -9999.0] = np.nan + return data, var_name + + +def get_nc_packing_info(nc_path, var_name=None): + """Get packing metadata from a NetCDF file. + + Returns + ------- + dict with keys: dtype, scale_factor, add_offset (or None if not packed) + """ + with Dataset(nc_path, 'r') as ds: + ds.set_auto_maskandscale(False) + if var_name is None: + var_name = _find_data_var(ds) + var = ds.variables[var_name] + ncattrs = var.ncattrs() + info = { + 'dtype': var.dtype, + 'scale_factor': var.getncattr('scale_factor') if 'scale_factor' in ncattrs else None, + 'add_offset': var.getncattr('add_offset') if 'add_offset' in ncattrs else None, + } + return info + + +# --------------------------------------------------------------------------- +# Test class +# --------------------------------------------------------------------------- + +@pytest.mark.slow +class TestScaleOffsetPacking: + """Test that int16 scale/offset packing produces outputs equivalent to float.""" + + case_dir = os.path.join(os.path.dirname(__file__), 'data', 'LF_ETRS89_UseCase') + settings_file = os.path.join(case_dir, 'settings', 'full.xml') + + # Variables to test: these have scale_factor/add_offset defined + # and use simple report options available in the test catchment. + # Theta1Maps: scale_factor=1.526e-5, add_offset=0.5 (range 0-1) + # Using repThetaMaps which produces Theta1Maps + + def _run_lisflood(self, output_dir, packing=False, dt_sec='86400', + step_start='30/07/2016 06:00', step_end='05/08/2016 06:00', + opts_to_set=None, opts_to_unset=None, new_vars=None): + """Run lisflood with specified settings and return output path.""" + full_out_dir = os.path.join(self.case_dir, 'out', output_dir) + if os.path.exists(full_out_dir): + shutil.rmtree(full_out_dir, ignore_errors=True) + os.makedirs(full_out_dir, exist_ok=True) + + base_opts_set = list(opts_to_set or []) + base_opts_unset = list(opts_to_unset or []) + base_new_vars = dict(new_vars or {}) + + # Configure packing + if packing: + base_new_vars['OutputPacking'] = 'True' + else: + base_new_vars['OutputPacking'] = 'False' + + settings = setoptions_with_new_vars( + self.settings_file, + opts_to_set=base_opts_set, + opts_to_unset=base_opts_unset, + vars_to_set={ + 'StepStart': step_start, + 'StepEnd': step_end, + 'DtSec': dt_sec, + 'PathOut': full_out_dir, + }, + new_vars=base_new_vars, + ) + lisfloodexe(settings) + return full_out_dir + + def test_packing_all_variables(self): + """All variables with scale_factor/add_offset should match float output within tolerance. + + Dynamically discovers all packed variables from default_options and checks + every one that the model produces in this configuration. + """ + # Enable as many report options as possible to produce packed variables + opts = [ + 'repThetaMaps', 'repThetaForestMaps', 'repThetaIrrigationMaps', + 'repE2O2', 'repUZMaps', 'repGwPercUZLZMaps', + 'repSnowMaps', 'repSnowCoverMaps', 'repSnowMeltMaps', + 'repDischargeMaps', 'repSurfaceRunoffMaps', + 'repFastRunoffMaps', 'repInfiltrationMaps', 'repInterceptionMaps', + 'repTotalRunoffMaps', 'repWaterDepthMaps', + 'repESActMaps', 'repETActMaps', 'repETRefMaps', 'repEWIntMaps', + 'repTaMaps', 'repRainMaps', 'repPrefFlowMaps', + 'repSeepSubToGWMaps', 'repUZOutflowMaps', + ] + + # Run without packing (float64 output) + out_float = self._run_lisflood( + 'test_packing_float', + packing=False, + opts_to_set=opts, + ) + + # Run with packing (int16 output) + out_packed = self._run_lisflood( + 'test_packing_int16', + packing=True, + opts_to_set=opts, + ) + + # Build lookup: all variables that have scale_factor defined + reportedmaps = default_options['reportedmaps'] + packed_vars = { + name: rm for name, rm in reportedmaps.items() + if getattr(rm, 'scale_factor', None) is not None + } + + checked_count = 0 + + for filename in sorted(os.listdir(out_packed)): + if not filename.endswith('.nc'): + continue + + nc_float = os.path.join(out_float, filename) + nc_packed = os.path.join(out_packed, filename) + + if not os.path.exists(nc_float): + continue + + info_packed = get_nc_packing_info(nc_packed) + if info_packed['dtype'] != np.dtype('int16'): + continue # not packed, skip + + # Get tolerance from the file's own scale_factor/add_offset attributes + scale_factor = info_packed['scale_factor'] + add_offset = info_packed['add_offset'] + + data_float, _ = read_nc_variable(nc_float) + data_packed, _ = read_nc_variable(nc_packed) + + valid = ~np.isnan(data_float) & ~np.isnan(data_packed) + if not valid.any(): + continue + + # Assert no valid float values are outside the packing range + pack_min = add_offset + scale_factor * PACK_MIN + pack_max = add_offset + scale_factor * PACK_MAX + out_of_range = valid & ((data_float < pack_min) | (data_float > pack_max)) + assert not out_of_range.any(), \ + f"{filename}: {out_of_range.sum()} values outside packing range " \ + f"[{pack_min:.4g}, {pack_max:.4g}]. Scale/offset parameters need adjustment." + + # Compare packed vs float within quantization tolerance + tolerance = scale_factor # full step tolerance + max_diff = np.max(np.abs(data_float[valid] - data_packed[valid])) + assert max_diff <= tolerance, \ + f"Max difference {max_diff} exceeds tolerance {tolerance} for {filename}" + checked_count += 1 + + assert checked_count > 0, "No packed variables were checked" + + def teardown_method(self): + """Clean up output directories.""" + out_base = os.path.join(self.case_dir, 'out') + if os.path.exists(out_base): + for d in os.listdir(out_base): + if d.startswith('test_packing_'): + shutil.rmtree(os.path.join(out_base, d), ignore_errors=True) + + +@pytest.mark.slow +class TestTemporalAggregation: + """Test that temporal aggregation (monthly mean/sum) matches manual aggregation of daily outputs.""" + + case_dir = os.path.join(os.path.dirname(__file__), 'data', 'LF_ETRS89_UseCase') + settings_file = os.path.join(case_dir, 'settings', 'full.xml') + + def _run_lisflood(self, output_dir, dt_sec='86400', + step_start='02/07/2016 06:00', step_end='01/09/2016 06:00', + opts_to_set=None, opts_to_unset=None, new_vars=None): + """Run lisflood with specified settings.""" + full_out_dir = os.path.join(self.case_dir, 'out', output_dir) + if os.path.exists(full_out_dir): + shutil.rmtree(full_out_dir, ignore_errors=True) + os.makedirs(full_out_dir, exist_ok=True) + + base_opts_set = list(opts_to_set or []) + base_opts_unset = list(opts_to_unset or []) + base_new_vars = dict(new_vars or {}) + + settings = setoptions_with_new_vars( + self.settings_file, + opts_to_set=base_opts_set, + opts_to_unset=base_opts_unset, + vars_to_set={ + 'StepStart': step_start, + 'StepEnd': step_end, + 'DtSec': dt_sec, + 'PathOut': full_out_dir, + }, + new_vars=base_new_vars, + ) + lisfloodexe(settings) + return full_out_dir + + @pytest.mark.parametrize("frequency,operation", [ + ("monthly", "mean"), + ("monthly", "sum"), + ("yearly", "mean"), + ("yearly", "sum"), + ]) + def test_temporal_aggregation(self, frequency, operation): + """Temporal aggregation should match manual aggregation of daily outputs. + + Dynamically discovers all variables with scale_factor from default_options, + enables their report options, and verifies that the aggregated output + matches the manually computed aggregation from daily outputs. + + The aggregation writes at period boundaries (month-end or year-end), + so only complete periods produce output. + """ + # Choose time range: monthly needs ~2 months, yearly needs >1 year + if frequency == 'monthly': + step_start = '02/07/2016 06:00' + step_end = '01/09/2016 06:00' + else: # yearly + step_start = '02/01/2016 06:00' + step_end = '02/01/2017 06:00' + # Build list of all report options that produce packed variables + reportedmaps = default_options['reportedmaps'] + packed_vars = { + name: rm for name, rm in reportedmaps.items() + if getattr(rm, "scale_factor", None) is not None and rm.all and not rm.steps + } + # Collect all report options needed + all_report_opts = set() + for rm in packed_vars.values(): + all_report_opts.update(rm.all) + all_report_opts.discard('') + opts = list(all_report_opts) + + # Build semicolon-separated list of all packed variable names for aggregation + agg_var_list = ';'.join(packed_vars.keys()) + + # Select the aggregation setting key + agg_setting = f'Output{frequency.capitalize()}{operation.capitalize()}' + + # Run with daily all-steps output (no aggregation) + out_daily = self._run_lisflood( + f'test_agg_{frequency}_{operation}_daily', + step_start=step_start, + step_end=step_end, + opts_to_set=opts, + new_vars={ + 'OutputPacking': 'False', + 'OutputMonthlyMean': '', + 'OutputMonthlySum': '', + 'OutputYearlyMean': '', + 'OutputYearlySum': '', + }, + ) + + # Run with temporal aggregation for all packed variables + out_agg = self._run_lisflood( + f'test_agg_{frequency}_{operation}_agg', + step_start=step_start, + step_end=step_end, + opts_to_set=opts, + new_vars={ + 'OutputPacking': 'False', + 'OutputMonthlyMean': agg_var_list if agg_setting == 'OutputMonthlyMean' else '', + 'OutputMonthlySum': agg_var_list if agg_setting == 'OutputMonthlySum' else '', + 'OutputYearlyMean': agg_var_list if agg_setting == 'OutputYearlyMean' else '', + 'OutputYearlySum': agg_var_list if agg_setting == 'OutputYearlySum' else '', + }, + ) + + # Aggregation function for manual computation + agg_func = np.nanmean if operation == 'mean' else np.nansum + + checked_count = 0 + for filename in sorted(os.listdir(out_agg)): + if not filename.endswith('.nc'): + continue + + nc_daily_path = os.path.join(out_daily, filename) + nc_agg_path = os.path.join(out_agg, filename) + + if not os.path.exists(nc_daily_path): + continue + + # Load daily data + with Dataset(nc_daily_path, 'r') as ds: + time_var = ds.variables['time'] + times = time_var[:] + time_units = time_var.units + calendar = time_var.calendar + + from netCDF4 import num2date + dates = num2date(times, time_units, calendar) + + var_name = _find_data_var(ds) + daily_data = ds.variables[var_name][:] + + # Convert to float with NaN for masked values + if hasattr(daily_data, 'filled'): + daily_data = daily_data.filled(np.nan).astype(np.float64) + daily_data[daily_data == -9999.0] = np.nan + + # Group daily data by period (month or year) + dt_day = 1 + period_groups = {} + for i, d in enumerate(dates): + if frequency == 'monthly': + period_key = (d.year, d.month) + else: + period_key = d.year + if period_key not in period_groups: + period_groups[period_key] = [] + period_groups[period_key].append(daily_data[i]) + + # Only keep completed periods (boundary reached) + completed_periods = set() + for i, d in enumerate(dates): + next_d = d + datetime.timedelta(days=dt_day) + if frequency == 'monthly': + if d.month != next_d.month: + completed_periods.add((d.year, d.month)) + else: + if d.year != next_d.year: + completed_periods.add(d.year) + + # Compute aggregation for each completed period + manual_agg = [] + for key in sorted(completed_periods): + stack = np.array(period_groups[key]) + manual_agg.append(agg_func(stack, axis=0)) + manual_agg = np.array(manual_agg) + + # Read aggregated output + data_agg, _ = read_nc_variable(nc_agg_path) + + # Only compare if the aggregated output has fewer time steps than daily + # (confirms aggregation actually happened for this variable) + if data_agg.shape[0] >= daily_data.shape[0]: + continue + + if data_agg.shape != manual_agg.shape: + continue + + valid = ~np.isnan(manual_agg) & ~np.isnan(data_agg) + if not valid.any(): + continue + + # Compare: absolute tolerance for mean, relative for sum + if operation == 'mean': + max_diff = np.max(np.abs(data_agg[valid] - manual_agg[valid])) + assert max_diff < 1e-6, \ + f"{filename}: {frequency} {operation} max difference {max_diff} exceeds tolerance 1e-6" + else: + max_rel_diff = np.max(np.abs( + (data_agg[valid] - manual_agg[valid]) / + np.where(manual_agg[valid] != 0, manual_agg[valid], 1.0) + )) + assert max_rel_diff < 1e-5, \ + f"{filename}: {frequency} {operation} max relative difference {max_rel_diff} exceeds tolerance 1e-5" + checked_count += 1 + + assert checked_count > 0, f"No aggregated variables were checked for {frequency} {operation}" + + def test_aggregation_disables_packing(self): + """Aggregated outputs should NOT use int16 packing even when OutputPacking=True. + + This is because scale/offset ranges are calibrated for instantaneous daily values, + not for accumulated monthly/yearly values. + """ + out_dir = self._run_lisflood( + 'test_agg_no_packing', + step_start='02/07/2016 06:00', + step_end='01/09/2016 06:00', + opts_to_set=['repThetaMaps', 'repE2O2'], + new_vars={ + 'OutputPacking': 'True', + 'OutputMonthlyMean': 'Theta1Maps', + 'OutputMonthlySum': '', + 'OutputYearlyMean': '', + 'OutputYearlySum': '', + }, + ) + + nc_path = os.path.join(out_dir, 'tha.nc') + assert os.path.exists(nc_path), f"Output not found: {nc_path}" + + info = get_nc_packing_info(nc_path) + # Aggregated outputs should remain float (not packed) + assert info['dtype'] != np.dtype('int16'), \ + "Aggregated output should NOT be int16-packed" + assert info['scale_factor'] is None, \ + "Aggregated output should not have scale_factor attribute" + + def teardown_method(self): + """Clean up output directories.""" + out_base = os.path.join(self.case_dir, 'out') + if os.path.exists(out_base): + for d in os.listdir(out_base): + if d.startswith('test_agg_'): + shutil.rmtree(os.path.join(out_base, d), ignore_errors=True) From 434d42151a41dd2a9ee683d0b5b63ed95105f6f4 Mon Sep 17 00:00:00 2001 From: doc78 Date: Wed, 5 Aug 2026 07:04:19 +0000 Subject: [PATCH 32/36] Modified Ta Maps scale and offset to fit the correct range. Rounded up scal value instead of down to avoid min upper than zero. --- .../global_modules/default_options.py | 166 +++++++++--------- tests/test_scale_offset_aggregation.py | 18 +- 2 files changed, 92 insertions(+), 92 deletions(-) diff --git a/src/lisflood/global_modules/default_options.py b/src/lisflood/global_modules/default_options.py index ee7184db..afea152c 100644 --- a/src/lisflood/global_modules/default_options.py +++ b/src/lisflood/global_modules/default_options.py @@ -352,7 +352,7 @@ output_var='DirectRunoff', unit='mm', end=[], steps=['repSurfaceRunoffMaps'], all=[''], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.006, add_offset=200.0), + yearly=False, scale_factor=0.0062, add_offset=200.0), 'DischargeEnd': ReportedMap(name='DischargeEnd', output_var='ChanQAvg', unit='m3/s', end=[], steps=[], all=[], restrictoption=[], monthly=False, @@ -369,46 +369,46 @@ 'ESActForestMaps': ReportedMap(name='ESActForestMaps', output_var='ESAct[1]', unit='mm', end=[], steps=[''], all=['repESActMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False,scale_factor=3.05e-4, add_offset=10.), + monthly=False, yearly=False,scale_factor=0.00031, add_offset=10.), 'ESActMaps': ReportedMap(name='ESActMaps', output_var='ESActPixel', unit='mm', end=[], steps=[], all=['repESActMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=3.05e-4, add_offset=10.0), + scale_factor=0.00031, add_offset=10.0), 'ESRefMapsOut': ReportedMap(name='ESRefMapsOut', output_var='ESRef', unit='mm', end=[], steps=[], all=['repESRefMaps'], restrictoption=[], monthly=False, yearly=False, - scale_factor=3.05e-4, add_offset=10.0), + scale_factor=0.00031, add_offset=10.0), 'ETActMaps': ReportedMap(name='ETActMaps', output_var='ESActPixel+self.var.TaPixel+self.var.TaInterceptionAll+self.var.EvaAddM3*self.var.M3toMM', unit='mm', end=[], steps=[], all=['repETActMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=0.0154, add_offset=495.0), + scale_factor=0.016, add_offset=495.0), 'ETActBudykoMaps': ReportedMap(name='ETActBudykoMaps', output_var='ESActNoIrrPixel+self.var.TaNoIrrPixel+self.var.TaInterceptionNoIrrPixel', unit='mm', end=[], steps=[], all=['repETActMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=0.0154, add_offset=495.0), + scale_factor=0.016, add_offset=495.0), 'ETRefMapsOut': ReportedMap(name='ETRefMapsOut', output_var='ETRef', unit='mm', end=[], steps=[], all=['repETRefMaps'], restrictoption=[], monthly=False, yearly=False, - scale_factor=3.05e-4, add_offset=10.0), + scale_factor=0.00031, add_offset=10.0), 'EWIntForestMaps': ReportedMap(name='EWIntForestMaps', output_var='TaInterception[1]', unit='mm', end=[], steps=[], all=['repEWIntMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=3.05e-4, add_offset=10.0), + yearly=False, scale_factor=0.00031, add_offset=10.0), 'EWIntMaps': ReportedMap(name='EWIntMaps', output_var='TaInterceptionAll', unit='mm', end=[], steps=[], all=['repEWIntMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=3.05e-4, add_offset=10.0), + scale_factor=0.00031, add_offset=10.0), 'EWRefMapsOut': ReportedMap(name='EWRefMapsOut', output_var='EWRef', unit='mm', end=[], steps=[], all=['repEWRefMaps'], restrictoption=[], monthly=False, yearly=False, - scale_factor=3.05e-4, add_offset=10.0), + scale_factor=0.00031, add_offset=10.0), 'EWater': ReportedMap(name='EWater', output_var='EvaAddM3*self.var.M3toMM', unit='mm', end=[], steps=[], all=['repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=3.05e-4, add_offset=10.0), + scale_factor=0.00031, add_offset=10.0), 'FalkenmarkM3Capita1': ReportedMap(name='FalkenmarkM3Capita1', output_var='FalkenmarkM3Capita1', unit='M3Capita', end=[], @@ -435,7 +435,7 @@ output_var='SurfaceRunoff+self.var.UZOutflowPixel', unit='mm', end=[], steps=[], all=['repFastRunoffMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.0076, add_offset=250), + yearly=False, scale_factor=0.0077, add_offset=250), 'FossilGroundwaterUsedM3': ReportedMap(name='FossilGroundwaterUsedM3', output_var='FossilGroundwaterUsedM3', unit='m3', end=[], @@ -469,49 +469,49 @@ end=[], steps=['repGwPercUZLZMaps'], all=['repGwPercUZLZMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.6e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-05, add_offset=1.5), 'GwPercUZLZIrrigationMaps': ReportedMap(name='GwPercUZLZForestMaps', output_var='GwPercUZLZ[2]', unit='mm', end=[], steps=['repGwPercUZLZMaps'], all=['repGwPercUZLZMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.6e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-05, add_offset=1.5), 'GwPercUZLZOtherMaps': ReportedMap(name='GwPercUZLZForestMaps', output_var='GwPercUZLZ[0]', unit='mm', end=[], steps=[], all=['repGwPercUZLZMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.6e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-05, add_offset=1.5), 'GwPercUZLZMaps': ReportedMap(name='GwPercUZLZMaps', output_var='GwPercUZLZPixel', unit='mm', end=[], steps=[], all=['repGwPercUZLZMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.6e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-05, add_offset=1.5), 'InfiltrationForestMaps': ReportedMap(name='InfiltrationForestMaps', output_var='Infiltration[1]', unit='mm', end=[], steps=[], all=['repInfiltrationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.0076, add_offset=250.), + yearly=False, scale_factor=0.0077, add_offset=250.), 'InfiltrationMaps': ReportedMap(name='InfiltrationMaps', output_var='Infiltration[0]', unit='mm', end=[], steps=[], all=['repInfiltrationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.0076, add_offset=250.), + yearly=False, scale_factor=0.0077, add_offset=250.), 'InterceptionForestMaps': ReportedMap(name='InterceptionForestMaps', output_var='Interception[1]', unit='mm', end=[], steps=[], all=['repInterceptionMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=2.3e-4, add_offset=7.5), + yearly=False, scale_factor=0.00023, add_offset=7.5), 'InterceptionMaps': ReportedMap(name='InterceptionMaps', output_var='Interception[0]', unit='mm', end=[], steps=[], all=['repInterceptionMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=2.3e-4, add_offset=7.5), + yearly=False, scale_factor=0.00023, add_offset=7.5), 'LocalFreshwaterM3': ReportedMap(name='LocalFreshwaterM3', output_var='LocalFreshwaterM3', unit='m3', end=[], @@ -539,16 +539,16 @@ restrictoption=[], monthly=False, yearly=False), 'LZMaps': ReportedMap(name='LZMaps', output_var='LZ', unit='mm', end=[], steps=[], all=['repLZMaps', 'repE2O2'], restrictoption=['nonInit'], - monthly=False, yearly=False,scale_factor=0.2365, add_offset=7250.0), + monthly=False, yearly=False,scale_factor=0.23, add_offset=7500.0), 'LZOutflowMaps': ReportedMap(name='LZOutflowMaps', output_var='LZOutflowToChannelPixel', unit='mm', end=[], steps=[], all=['repLZOutflowMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor= 4.578e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-05, add_offset=1.5), 'LZState': ReportedMap(name='LZState', output_var='LZ', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=0.09156, add_offset=-1000.0), + scale_factor=0.092, add_offset=-1000.0), 'LakeAbstractionM3': ReportedMap(name='LakeAbstractionM3', output_var='LakeAbstractionM3', unit='m3', end=[], steps=['repTotalAbs'], all=[], @@ -707,34 +707,34 @@ output_var='SeepTopToSubA[0]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.6e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-05, add_offset=1.5), 'Percolation1ato1bForestMaps': ReportedMap(name='Percolation1ato1bForestMaps', output_var='SeepTopToSubA[1]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.6e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-05, add_offset=1.5), 'Percolation1ato1bIrrigationMaps': ReportedMap(name='Percolation1ato1bIrrigationMaps', output_var='SeepTopToSubA[2]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.6e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-05, add_offset=1.5), 'Percolation1bto2OtherMaps': ReportedMap(name='Percolation1bto2OtherMaps', output_var='SeepTopToSubB[0]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.6e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-05, add_offset=1.5), 'Percolation1bto2ForestMaps': ReportedMap(name='Percolation1bto2ForestMaps', output_var='SeepTopToSubB[1]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.6e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-05, add_offset=1.5), 'Percolation1bto2IrrigationMaps': ReportedMap(name='Percolation1bto2IrrigationMaps', output_var='SeepTopToSubB[2]', unit='mm', end=[], steps=[], all=['repPercolationMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.6e-5, add_offset=1.5), + yearly=False, scale_factor=4.6e-05, add_offset=1.5), 'PrevCmMCTEnd': ReportedMap(name='PrevCmMCTEnd', output_var='PrevCm0', unit='-', end=['repEndMaps'], steps=[], all=[], restrictoption=['nonInit','MCTRouting'], monthly=False, yearly=False), @@ -769,7 +769,7 @@ unit='mm/timestep', end=[], steps=[], all=['repPrecipitationMaps'], restrictoption=[], monthly=False, - yearly=False, scale_factor=0.01526, add_offset=500.), + yearly=False, scale_factor=0.016, add_offset=500.), 'PrefFlowOtherMaps': ReportedMap(name='PrefFlowOtherMaps', output_var='PrefFlow[0]', unit='mm', end=[], steps=[], all=['repPrefFlowMaps'], @@ -792,7 +792,7 @@ 'RainMaps': ReportedMap(name='RainMaps', output_var='Rain', unit='mm', end=[], steps=[], all=['repRainMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=0.01526, add_offset=500.), + scale_factor=0.016, add_offset=500.), 'RegionMonthExternalInflowM3': ReportedMap(name='RegionMonthExternalInflowM3', output_var='RegionMonthExternalInflowM3', unit='M3', end=[], @@ -901,39 +901,39 @@ end=[], steps=[], all=['repSeepSubToGWMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=9.156e-4, add_offset=30.), + yearly=False, scale_factor=0.00092, add_offset=30.), 'SeepSubToGWforestMaps': ReportedMap(name='SeepSubToGWForestMaps', output_var='SeepSubToGW[1]', unit='mm', end=[], steps=[], all=['repSeepSubToGWMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=9.156e-4, add_offset=30.), + yearly=False, scale_factor=0.00092, add_offset=30.), 'SeepSubToGWirrigationMaps': ReportedMap(name='SeepSubToGWIrrigationMaps', output_var='SeepSubToGW[2]', unit='mm', end=[], steps=[], all=['repSeepSubToGWMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=9.156e-4, add_offset=30.), + yearly=False, scale_factor=0.00092, add_offset=30.), 'SeepSubToGWMaps': ReportedMap(name='SeepSubToGWMaps', output_var='SeepSubToGWPixel', unit='mm', end=[], steps=[], all=['repSeepSubToGWMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=9.156e-4, add_offset=30.), + yearly=False, scale_factor=0.00092, add_offset=30.), 'SeepTopToSubBAverageOtherMap': ReportedMap(name='SeepTopToSubBAverageOtherMap', output_var='SeepTopToSubBAv[0]', unit='mm/timestep', end=['InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, - yearly=False, scale_factor=9.156e-4, add_offset=30.), + yearly=False, scale_factor=0.00092, add_offset=30.), 'SeepTopToSubBAverageForestMap': ReportedMap(name='SeepTopToSubBAverageForestMap', output_var='SeepTopToSubBAv[1]', unit='mm/timestep', end=['InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, - yearly=False, scale_factor=9.156e-4, add_offset=30.), + yearly=False, scale_factor=0.00092, add_offset=30.), 'SeepTopToSubBAverageIrrigationMap': ReportedMap(name='SeepTopToSubBAverageIrrigationMap', output_var='SeepTopToSubBAv[2]', unit='mm/timestep', end=['InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, - yearly=False, scale_factor=9.156e-4, add_offset=30.), + yearly=False, scale_factor=0.00092, add_offset=30.), 'SnowCoverAEnd': ReportedMap(name='SnowCoverAEnd', output_var='SnowCoverS[0]', unit='mm', end=['repEndMaps'], steps=[], all=[], restrictoption=[], monthly=False, @@ -942,7 +942,7 @@ output_var='SnowCoverS[0]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.15260, add_offset=5000.), + yearly=False, scale_factor=0.16, add_offset=5000.), 'SnowCoverBEnd': ReportedMap(name='SnowCoverBEnd', output_var='SnowCoverS[1]', unit='mm', end=['repEndMaps'], steps=[], all=[], restrictoption=[], monthly=False, @@ -951,7 +951,7 @@ output_var='SnowCoverS[1]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.15260, add_offset=5000.), + yearly=False, scale_factor=0.16, add_offset=5000.), 'SnowCoverCEnd': ReportedMap(name='SnowCoverCEnd', output_var='SnowCoverS[2]', unit='mm', end=['repEndMaps'], steps=[], all=[], restrictoption=[], monthly=False, @@ -960,40 +960,40 @@ output_var='SnowCoverS[2]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.15260, add_offset=5000.), + yearly=False, scale_factor=0.16, add_offset=5000.), 'SnowCoverMaps': ReportedMap(name='SnowCoverMaps', output_var='SnowCover', unit='mm', end=[], steps=[], all=['repSnowCoverMaps','repE2O1'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.15260, add_offset=5000.), + yearly=False, scale_factor=0.16, add_offset=5000.), 'SnowMaps': ReportedMap(name='SnowMaps', output_var='Snow', unit='mm', end=[], steps=[], all=['repSnowMaps'], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=0.003052, add_offset=100.), + scale_factor=0.0031, add_offset=100.), 'SnowMeltMaps': ReportedMap(name='SnowMeltMaps', output_var='SnowMelt', unit='mm', end=[], steps=[], all=['repSnowMeltMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.003815, add_offset=125.), + yearly=False, scale_factor=0.0039, add_offset=125.), 'SurfaceRunoffMaps': ReportedMap(name='SurfaceRunoffMaps', output_var='SurfaceRunoff', unit='mm', end=[], steps=[], all=['repSurfaceRunoffMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.0076, add_offset=250.), + yearly=False, scale_factor=0.0077, add_offset=250.), 'TaOtherMaps': ReportedMap(name='TaOtherMaps', output_var='Ta[0]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=3.815e-4, add_offset=2.5), + yearly=False, scale_factor=0.00039, add_offset=2.5), 'TaForestMaps': ReportedMap(name='TaForestMaps', output_var='Ta[1]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=3.815e-4, add_offset=2.5), + yearly=False, scale_factor=0.00039, add_offset=2.5), 'TaIrrigationMaps': ReportedMap(name='TaIrrigationMaps', output_var='Ta[2]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=3.815e-4, add_offset=2.5), + yearly=False, scale_factor=0.00039, add_offset=2.5), 'TaMaps': ReportedMap(name='TaMaps', output_var='TaPixel', unit='mm', end=[], steps=[], all=['repE2O1','repTaMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=3.815e-4, add_offset=2.5), + monthly=False, yearly=False, scale_factor=0.00039, add_offset=2.5), 'TavgMapsOut': ReportedMap(name='TavgMapsOut', output_var='Tavg', unit='degree', end=[], steps=[], all=['repTavgMaps'], restrictoption=[], monthly=False, yearly=False), @@ -1008,12 +1008,12 @@ unit='', end=[], steps=[], all=['repThetaForestMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta1ForestState': ReportedMap(name='Theta1ForestState', output_var='Theta1a[1]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta1IrrigationEnd': ReportedMap(name='Theta1IrrigationEnd', output_var='Theta1a[2]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], @@ -1024,20 +1024,20 @@ end=[], steps=[], all=['repThetaIrrigationMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta1IrrigationState': ReportedMap(name='Theta1IrrigationState', output_var='Theta1a[2]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta1Maps': ReportedMap(name='Theta1Maps', output_var='Theta1a[0]', unit='', end=[], steps=[], all=['repThetaMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta1State': ReportedMap(name='Theta1State', output_var='Theta1a[0]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta2End': ReportedMap(name='Theta2End', output_var='Theta1b[0]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, yearly=False), @@ -1049,12 +1049,12 @@ unit='', end=[], steps=[], all=['repThetaForestMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta2ForestState': ReportedMap(name='Theta2ForestState', output_var='Theta1b[1]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta2IrrigationEnd': ReportedMap(name='Theta2IrrigationEnd', output_var='Theta1b[2]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], @@ -1065,20 +1065,20 @@ end=[], steps=[], all=['repThetaIrrigationMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta2IrrigationState': ReportedMap(name='Theta2IrrigationState', output_var='Theta1b[2]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta2Maps': ReportedMap(name='Theta2Maps', output_var='Theta1b[0]', unit='', end=[], steps=[], all=['repThetaMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta2State': ReportedMap(name='Theta2State', output_var='Theta1b[0]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta3End': ReportedMap(name='Theta3End', output_var='Theta2[0]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], restrictoption=[], monthly=False, yearly=False), @@ -1090,12 +1090,12 @@ unit='', end=[], steps=[], all=['repThetaForestMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta3ForestState': ReportedMap(name='Theta3ForestState', output_var='Theta2[1]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta3IrrigationEnd': ReportedMap(name='Theta3IrrigationEnd', output_var='Theta2[2]', unit='', end=['repEndMaps','InitLisflood'], steps=[], all=[], @@ -1105,20 +1105,20 @@ output_var='Theta2[2]', unit='', end=[], steps=[], all=['repThetaIrrigationMaps','repThetaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta3IrrigationState': ReportedMap(name='Theta3IrrigationState', output_var='Theta2[2]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta3Maps': ReportedMap(name='Theta3Maps', output_var='Theta2[0]', unit='', end=[], steps=[], all=['repThetaMaps','repE2O2'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'Theta3State': ReportedMap(name='Theta3State', output_var='Theta2[0]', unit='', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=1.53e-5, add_offset=0.5), + yearly=False, scale_factor=1.6e-05, add_offset=0.5), 'TotalAbsGroundwater': ReportedMap(name='TotalAbsGroundwater', output_var='abstraction_GW_actual_M3*self.var.M3toMM', unit='mm', end=[], steps=['repTotalAbs'], @@ -1163,17 +1163,17 @@ output_var='TotalRunoff', unit='mm', end=[], steps=[], all=['repTotalRunoffMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=0.0076, add_offset=250.), + monthly=False, yearly=False, scale_factor=0.0077, add_offset=250.), 'TotalToChanMaps': ReportedMap(name='TotalToChanMaps', output_var='ToChanM3Runoff*self.var.M3toMM', unit='mm', end=[], steps=[], all=['repTotalRunoffMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.005341, add_offset=175.), + yearly=False, scale_factor=0.0054, add_offset=175.), 'TransLossMaps': ReportedMap(name='TransLossMaps', output_var='TransLossM3*self.var.M3toMM', unit='mm', end=[], steps=[], all=['repGwLossMaps','repE2O2'], restrictoption=['nonInit','TransLoss'], monthly=False, - yearly=False, scale_factor=0.009156, add_offset=300.), + yearly=False, scale_factor=0.0092, add_offset=300.), 'UpstreamInflowUsedM3': ReportedMap(name='UpstreamInflowUsedM3', output_var='UpstreamInflowUsedM3', unit='M3', end=[], steps=['repWaterUse'], @@ -1194,11 +1194,11 @@ 'UZForestMaps': ReportedMap(name='UZForestMaps', output_var='UZ[1]', unit='mm', end=[], steps=[], all=['repUZMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.05341, add_offset=1750.), + yearly=False, scale_factor=0.054, add_offset=1750.), 'UZForestState': ReportedMap(name='UZForestState', output_var='UZ[1]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.05341, add_offset=1750.), + yearly=False, scale_factor=0.054, add_offset=1750.), 'UZIrrigationEnd': ReportedMap(name='UZIrrigationEnd', output_var='UZ[2]', unit='mm', end=['repEndMaps','InitLisflood'], steps=[], all=[], restrictoption=[], @@ -1206,41 +1206,41 @@ 'UZIrrigationMaps': ReportedMap(name='UZIrrigationMaps', output_var='UZ[2]', unit='mm', end=[], steps=[], all=['repUZMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=0.05341, add_offset=1750.), + monthly=False, yearly=False, scale_factor=0.054, add_offset=1750.), 'UZIrrigationState': ReportedMap(name='UZIrrigationState', output_var='UZ[2]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=0.05341, add_offset=1750.), + monthly=False, yearly=False, scale_factor=0.054, add_offset=1750.), 'UZMaps': ReportedMap(name='UZMaps', output_var='UZ[0]', unit='mm', end=[], steps=[], all=['repUZMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=0.05341, add_offset=1750.), + monthly=False, yearly=False, scale_factor=0.054, add_offset=1750.), 'UZOutflowForestMaps': ReportedMap(name='UZOutflowForestMaps', output_var='UZOutflow[1]', unit='mm', end=[], steps=[], all=['repUZOutflowMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.004578, add_offset=150.), + yearly=False, scale_factor=0.0046, add_offset=150.), 'UZOutflowIrrigationMaps': ReportedMap(name='UZOutflowIrrigationMaps', output_var='UZOutflow[2]', unit='mm', end=[], steps=[], all=['repUZOutflowMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.004578, add_offset=150.), + yearly=False, scale_factor=0.0046, add_offset=150.), 'UZOutflowOtherMaps': ReportedMap(name='UZOutflowOtherMaps', output_var='UZOutflow[0]', unit='mm', end=[], steps=[], all=['repUZOutflowMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.004578, add_offset=150.), + yearly=False, scale_factor=0.0046, add_offset=150.), 'UZOutflowMaps': ReportedMap(name='UZOutflowMaps', output_var='UZOutflowPixel', unit='mm', end=[], steps=[], all=['repUZOutflowMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.004578, add_offset=150.), + yearly=False, scale_factor=0.0046, add_offset=150.), 'UZState': ReportedMap(name='UZState', output_var='UZ[0]', unit='mm', end=[], steps=['repStateMaps'], all=[], restrictoption=['nonInit'], monthly=False, yearly=False, - scale_factor=0.05341, add_offset=1750.), + scale_factor=0.054, add_offset=1750.), 'WEI_Abs': ReportedMap(name='WEI_Abs', output_var='WEI_Abs', unit='-', end=[], steps=['repWIndex'], all=[], restrictoption=['nonInit', 'wateruse', 'indicator'], @@ -1271,17 +1271,17 @@ unit='m', end=[], steps=[], all=['repWaterDepthMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.003815, add_offset=125.), + yearly=False, scale_factor=0.0039, add_offset=125.), 'WaterDepthState': ReportedMap(name='WaterDepthState', output_var='WaterDepth', unit='m', end=[], steps=[], all=[], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=0.003815, add_offset=125.), + monthly=False, yearly=False, scale_factor=0.0039, add_offset=125.), 'TotalWaterStorageMaps': ReportedMap(name='TotalWaterStorageMaps', output_var='TotalWaterStorageMM', unit='mm', end=[], steps=[], all=['repTotalWaterStorageMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=534.4, add_offset=17497500.0), + monthly=False, yearly=False, scale_factor=5.4e+02, add_offset=17497500.0), 'WaterSecurityIndex': ReportedMap(name='WaterSecurityIndex', output_var='WaterSecurityIndex', unit='-', end=[], steps=['repWIndex'], all=[], diff --git a/tests/test_scale_offset_aggregation.py b/tests/test_scale_offset_aggregation.py index 9e5b586d..898b87c0 100644 --- a/tests/test_scale_offset_aggregation.py +++ b/tests/test_scale_offset_aggregation.py @@ -535,11 +535,11 @@ def test_temporal_aggregation(self, frequency, operation): assert checked_count > 0, f"No aggregated variables were checked for {frequency} {operation}" - def test_aggregation_disables_packing(self): - """Aggregated outputs should NOT use int16 packing even when OutputPacking=True. + def test_aggregation_sum_disables_packing(self): + """Sum-aggregated outputs should NOT use int16 packing even when OutputPacking=True. - This is because scale/offset ranges are calibrated for instantaneous daily values, - not for accumulated monthly/yearly values. + Monthly/yearly sums can exceed the int16 range calibrated for daily values, + so packing is disabled for sum aggregates. """ out_dir = self._run_lisflood( 'test_agg_no_packing', @@ -548,8 +548,8 @@ def test_aggregation_disables_packing(self): opts_to_set=['repThetaMaps', 'repE2O2'], new_vars={ 'OutputPacking': 'True', - 'OutputMonthlyMean': 'Theta1Maps', - 'OutputMonthlySum': '', + 'OutputMonthlyMean': '', + 'OutputMonthlySum': 'Theta1Maps', 'OutputYearlyMean': '', 'OutputYearlySum': '', }, @@ -559,11 +559,11 @@ def test_aggregation_disables_packing(self): assert os.path.exists(nc_path), f"Output not found: {nc_path}" info = get_nc_packing_info(nc_path) - # Aggregated outputs should remain float (not packed) + # Sum-aggregated outputs should remain float (not packed) assert info['dtype'] != np.dtype('int16'), \ - "Aggregated output should NOT be int16-packed" + "Sum-aggregated output should NOT be int16-packed" assert info['scale_factor'] is None, \ - "Aggregated output should not have scale_factor attribute" + "Sum-aggregated output should not have scale_factor attribute" def teardown_method(self): """Clean up output directories.""" From 82e2e7c8d5130756453137805f1a4ea673f74725 Mon Sep 17 00:00:00 2001 From: doc78 Date: Wed, 5 Aug 2026 07:11:04 +0000 Subject: [PATCH 33/36] Removed temporary tracking files --- packing_replacements.md | 126 --------------------------------- packing_scale_offset_values.md | 57 --------------- 2 files changed, 183 deletions(-) delete mode 100644 packing_replacements.md delete mode 100644 packing_scale_offset_values.md diff --git a/packing_replacements.md b/packing_replacements.md deleted file mode 100644 index c517bccb..00000000 --- a/packing_replacements.md +++ /dev/null @@ -1,126 +0,0 @@ -# Find-and-Replace Guide: scale_factor / add_offset Values - -Replace `scale_factor=1, add_offset=0` with the correct values below. -Use your editor's find-and-replace on each variable name to locate it. - -**Important:** For State/End entries, REMOVE scale_factor and add_offset entirely -(let them default to None). They should never be packed. - ---- - -## Variables to REMOVE packing from (State/End maps — set to None) - -These have `scale_factor=1, add_offset=0` but should NOT be packed. -Remove the `, scale_factor=1, add_offset=0` from these entries entirely: - -- SnowCoverAEnd, SnowCoverAState -- SnowCoverBEnd, SnowCoverBState -- SnowCoverCEnd, SnowCoverCState -- Theta1End, Theta1State, Theta1ForestState, Theta1IrrigationState -- Theta2ForestState, Theta2IrrigationState, Theta2State -- Theta3ForestState, Theta3IrrigationState, Theta3State -- UZForestState, UZIrrigationState, UZState -- WaterDepthState -- SeepTopToSubBAverageOtherMap (end=['InitLisflood'] — this is a prerun end map) -- SeepTopToSubBAverageForestMap (end=['InitLisflood']) -- SeepTopToSubBAverageIrrigationMap (end=['InitLisflood']) - ---- - -## Variables to UPDATE with proper values - -Format: `VariableName` → `scale_factor=X, add_offset=Y` -Design range and precision shown for reference. - -### Discharge (m3/s) — range 0 to 400,000 -- `DischargeMaps` → `scale_factor=6.104, add_offset=200000.0` - -### Direct Runoff (mm) — range 0 to 400 -- `DirectRunoffMaps` → `scale_factor=0.006104, add_offset=200.0` - -### Evaporation (mm/day) — range 0 to 20 -- `ESActMaps` → `scale_factor=3.052e-4, add_offset=10.0` -- `ESRefMapsOut` → `scale_factor=3.052e-4, add_offset=10.0` - -### ET (mm/day) — range -10 to 1000 -- `ETActMaps` → `scale_factor=0.01541, add_offset=495.0` -- `ETActBudykoMaps` → `scale_factor=0.01541, add_offset=495.0` -- `ETRefMapsOut` → `scale_factor=3.052e-4, add_offset=10.0` - -### Interception/Transpiration (mm/day) — range 0 to 15 -- `EWIntForestMaps` → `scale_factor=2.289e-4, add_offset=7.5` -- `EWIntMaps` → `scale_factor=2.289e-4, add_offset=7.5` -- `EWRefMapsOut` → `scale_factor=3.052e-4, add_offset=10.0` -- `EWater` → `scale_factor=3.052e-4, add_offset=10.0` -- `InterceptionForestMaps` → `scale_factor=2.289e-4, add_offset=7.5` -- `InterceptionMaps` → `scale_factor=2.289e-4, add_offset=7.5` - -### Fast Runoff / Preferential Flow (mm) — range 0 to 400 -- `FastRunoffMaps` → `scale_factor=0.006104, add_offset=200.0` - -### GW Percolation UZ to LZ (mm) — range 0 to 3 -- `GwPercUZLZForestMaps` → `scale_factor=4.578e-5, add_offset=1.5` -- `GwPercUZLZIrrigationMaps` → `scale_factor=4.578e-5, add_offset=1.5` -- `GwPercUZLZOtherMaps` → `scale_factor=4.578e-5, add_offset=1.5` -- `GwPercUZLZMaps` → `scale_factor=4.578e-5, add_offset=1.5` - -### Infiltration (mm) — range 0 to 500 -- `InfiltrationForestMaps` → `scale_factor=0.007630, add_offset=250.0` -- `InfiltrationMaps` → `scale_factor=0.007630, add_offset=250.0` - -### Seep to GW (mm) — range 0 to 60 -- `SeepSubToGWMaps` → `scale_factor=9.156e-4, add_offset=30.0` - -### Snow (mm) — range 0 to 200 -- `SnowMaps` → `scale_factor=0.003052, add_offset=100.0` - -### Snow Cover (mm) — range 0 to 10000 -- `SnowCoverMaps` → `scale_factor=0.15260, add_offset=5000.0` - -### Snow Melt (mm) — range 0 to 250 -- `SnowMeltMaps` → `scale_factor=0.003815, add_offset=125.0` - -### Surface Runoff (mm) — range 0 to 500 -- `SurfaceRunoffMaps` → `scale_factor=0.007630, add_offset=250.0` - -### Transpiration (mm/day) — range -10 to 15 -- `TaOtherMaps` → `scale_factor=3.815e-4, add_offset=2.5` -- `TaForestMaps` → `scale_factor=3.815e-4, add_offset=2.5` -- `TaIrrigationMaps` → `scale_factor=3.815e-4, add_offset=2.5` -- `TaMaps` → `scale_factor=3.815e-4, add_offset=2.5` - -### Theta (soil moisture fraction) — range 0 to 1 -- `Theta1Maps` → `scale_factor=1.526e-5, add_offset=0.5` -- `Theta1ForestMaps` → `scale_factor=1.526e-5, add_offset=0.5` -- `Theta1IrrigationMaps` → `scale_factor=1.526e-5, add_offset=0.5` -- `Theta2Maps` → `scale_factor=1.526e-5, add_offset=0.5` -- `Theta2ForestMaps` → `scale_factor=1.526e-5, add_offset=0.5` -- `Theta2IrrigationMaps` → `scale_factor=1.526e-5, add_offset=0.5` -- `Theta3Maps` → `scale_factor=1.526e-5, add_offset=0.5` -- `Theta3ForestMaps` → `scale_factor=1.526e-5, add_offset=0.5` -- `Theta3IrrigationMaps` → `scale_factor=1.526e-5, add_offset=0.5` - -### Total Runoff (mm) — range 0 to 500 -- `TotalRunoffMaps` → `scale_factor=0.007630, add_offset=250.0` -- `TotalToChanMaps` → `scale_factor=0.007630, add_offset=250.0` - -### Transmission Loss (mm) — range 0 to 600 -- `TransLossMaps` → `scale_factor=0.009156, add_offset=300.0` - -### UZ (mm) — range 0 to 3500 -- `UZForestMaps` → `scale_factor=0.05341, add_offset=1750.0` -- `UZIrrigationMaps` → `scale_factor=0.05341, add_offset=1750.0` -- `UZMaps` → `scale_factor=0.05341, add_offset=1750.0` - -### UZ Outflow (mm) — range 0 to 300 -- `UZOutflowForestMaps` → `scale_factor=0.004578, add_offset=150.0` -- `UZOutflowIrrigationMaps` → `scale_factor=0.004578, add_offset=150.0` -- `UZOutflowOtherMaps` → `scale_factor=0.004578, add_offset=150.0` -- `UZOutflowMaps` → `scale_factor=0.004578, add_offset=150.0` - -### Water Depth (mm) — range 0 to 250 -- `WaterDepthMaps` → `scale_factor=0.003815, add_offset=125.0` - -### Total Water Storage (mm) — range -5000 to 35,000,000 -- `TotalWaterStorageMaps` → **DO NOT PACK** (range too large for int16). Remove scale_factor/add_offset. - diff --git a/packing_scale_offset_values.md b/packing_scale_offset_values.md deleted file mode 100644 index 859b85b3..00000000 --- a/packing_scale_offset_values.md +++ /dev/null @@ -1,57 +0,0 @@ -# Scale/Offset Packing Values — Current Implementation - -CF-convention int16 packing as implemented in `default_options.py`. -Formula: `unpacked = packed * scale_factor + add_offset` -Precision = scale_factor / 2 - -## Packed Variables (Maps outputs) - -| Variable(s) | Unit | Design Range | scale_factor | add_offset | Precision (±) | -|-------------|------|--------------|--------------|------------|---------------| -| DischargeMaps | m3/s | 0 – 400,000 | 6.104 | 200000.0 | ±3.05 m3/s | -| DirectRunoffMaps | mm | 0 – 400 | 0.006104 | 200.0 | ±0.003 mm | -| ESActForestMaps, ESActMaps, ESRefMapsOut | mm | 0 – 20 | 3.052e-4 | 10.0 | ±1.5e-4 mm | -| ETActMaps, ETActBudykoMaps | mm | -10 – 1000 | 0.01541 | 495.0 | ±0.0077 mm | -| ETRefMapsOut | mm | 0 – 20 | 3.052e-4 | 10.0 | ±1.5e-4 mm | -| EWIntForestMaps, EWIntMaps | mm | 0 – 20 | 3.052e-4 | 10.0 | ±1.5e-4 mm | -| EWRefMapsOut, EWater | mm | 0 – 20 | 3.052e-4 | 10.0 | ±1.5e-4 mm | -| FastRunoffMaps | mm | 0 – 500 | 0.007630 | 250.0 | ±0.0038 mm | -| GwPercUZLZ (all variants) | mm | 0 – 3 | 4.578e-5 | 1.5 | ±2.3e-5 mm | -| InfiltrationForestMaps, InfiltrationMaps | mm | 0 – 500 | 0.007630 | 250.0 | ±0.0038 mm | -| InterceptionForestMaps, InterceptionMaps | mm | 0 – 15 | 2.289e-4 | 7.5 | ±1.1e-4 mm | -| MonthETactMM | mm | 0 – 300 | 0.004578 | 150.0 | ±0.0023 mm | -| MonthETdifMM | mm | -300 – 300 | 0.009156 | 0.0 | ±0.0046 mm | -| MonthETpotMM | mm | 0 – 300 | 0.004578 | 150.0 | ±0.0023 mm | -| PrecipitationMaps, RainMaps | mm | 0 – 1000 | 0.01526 | 500.0 | ±0.0076 mm | -| PrefFlow (all variants) | mm | 0 – 400 | 0.006104 | 200.0 | ±0.003 mm | -| SeepSubToGWMaps | mm | 0 – 60 | 9.156e-4 | 30.0 | ±4.6e-4 mm | -| SnowCoverMaps | mm | 0 – 10000 | 0.15260 | 5000.0 | ±0.076 mm | -| SnowMaps | mm | 0 – 200 | 0.003052 | 100.0 | ±0.0015 mm | -| SnowMeltMaps | mm | 0 – 250 | 0.003815 | 125.0 | ±0.0019 mm | -| SurfaceRunoffMaps | mm | 0 – 500 | 0.007630 | 250.0 | ±0.0038 mm | -| TaOtherMaps, TaForestMaps, TaIrrigationMaps, TaMaps | mm | -10 – 15 | 3.815e-4 | 2.5 | ±1.9e-4 mm | -| Theta (all Maps variants: 1/2/3, Other/Forest/Irrigation) | - | 0 – 1 | 1.526e-5 | 0.5 | ±7.6e-6 | -| TotalRunoffMaps, TotalToChanMaps | mm | 0 – 500 | 0.007630 | 250.0 | ±0.0038 mm | -| TransLossMaps | mm | 0 – 600 | 0.009156 | 300.0 | ±0.0046 mm | -| UZForestMaps, UZIrrigationMaps, UZMaps | mm | 0 – 3500 | 0.05341 | 1750.0 | ±0.027 mm | -| UZOutflow (all variants) | mm | 0 – 300 | 0.004578 | 150.0 | ±0.0023 mm | -| WaterDepthMaps | mm | 0 – 250 | 0.003815 | 125.0 | ±0.0019 mm | - -## NOT Packed (scale_factor = None) - -These variables have no packing defined and will always be written as float: - -- All `*End` maps (End maps — warm start, full precision needed) -- All `*State` maps (State maps — warm start, full precision needed) -- TotalWaterStorageMaps (range too large for useful int16 precision) -- TavgMapsOut (temperature — no packing defined) -- All water use / indicator variables (monthly aggregations, various ranges) -- FalkenmarkM3Capita1, EFlowIndicator, etc. (specialized indicators) - -## Notes - -- Packing is only active when `OutputPacking = True` in settings XML -- All values derived from GloFAS global run observed min/max with 20-50% headroom -- Theta uses theoretical range 0–1 (physically bounded) -- Precision column shows maximum quantization error (half a scale_factor step) -- Clipping warning fires once per variable if values exceed design range From 2cbbbe9a72533025ec733beba270221cae1671a5 Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Wed, 5 Aug 2026 11:02:02 +0200 Subject: [PATCH 34/36] transpiration scale offset update --- src/lisflood/global_modules/default_options.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lisflood/global_modules/default_options.py b/src/lisflood/global_modules/default_options.py index afea152c..0e26d7b1 100644 --- a/src/lisflood/global_modules/default_options.py +++ b/src/lisflood/global_modules/default_options.py @@ -982,18 +982,18 @@ 'TaOtherMaps': ReportedMap(name='TaOtherMaps', output_var='Ta[0]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.00039, add_offset=2.5), + yearly=False, scale_factor=0.00031, add_offset=10.0), 'TaForestMaps': ReportedMap(name='TaForestMaps', output_var='Ta[1]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.00039, add_offset=2.5), + yearly=False, scale_factor=0.00031, add_offset=10.0), 'TaIrrigationMaps': ReportedMap(name='TaIrrigationMaps', output_var='Ta[2]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.00039, add_offset=2.5), + yearly=False, scale_factor=0.00031, add_offset=10.0), 'TaMaps': ReportedMap(name='TaMaps', output_var='TaPixel', unit='mm', end=[], steps=[], all=['repE2O1','repTaMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=0.00039, add_offset=2.5), + monthly=False, yearly=False, scale_factor=0.00031, add_offset=10.0), 'TavgMapsOut': ReportedMap(name='TavgMapsOut', output_var='Tavg', unit='degree', end=[], steps=[], all=['repTavgMaps'], restrictoption=[], monthly=False, yearly=False), From 20ed76d92960cc65bd97ccfa977396b2b5aaa6dd Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Thu, 6 Aug 2026 11:23:11 +0200 Subject: [PATCH 35/36] Update ta ranges --- src/lisflood/global_modules/default_options.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lisflood/global_modules/default_options.py b/src/lisflood/global_modules/default_options.py index 0e26d7b1..fe6f02f7 100644 --- a/src/lisflood/global_modules/default_options.py +++ b/src/lisflood/global_modules/default_options.py @@ -982,18 +982,18 @@ 'TaOtherMaps': ReportedMap(name='TaOtherMaps', output_var='Ta[0]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.00031, add_offset=10.0), + yearly=False, scale_factor=4.6e-4, add_offset=15.0), 'TaForestMaps': ReportedMap(name='TaForestMaps', output_var='Ta[1]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.00031, add_offset=10.0), + yearly=False, scale_factor=4.6e-4, add_offset=15.0), 'TaIrrigationMaps': ReportedMap(name='TaIrrigationMaps', output_var='Ta[2]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=0.00031, add_offset=10.0), + yearly=False, scale_factor=4.6e-4, add_offset=15.0), 'TaMaps': ReportedMap(name='TaMaps', output_var='TaPixel', unit='mm', end=[], steps=[], all=['repE2O1','repTaMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=0.00031, add_offset=10.0), + monthly=False, yearly=False, scale_factor=4.6e-4, add_offset=15.0), 'TavgMapsOut': ReportedMap(name='TavgMapsOut', output_var='Tavg', unit='degree', end=[], steps=[], all=['repTavgMaps'], restrictoption=[], monthly=False, yearly=False), From cc5e21210b1750321249c5fe7855417ba784a0db Mon Sep 17 00:00:00 2001 From: Timo Schaffhauser Date: Thu, 6 Aug 2026 23:57:24 +0200 Subject: [PATCH 36/36] Update neg. range tact --- src/lisflood/global_modules/default_options.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lisflood/global_modules/default_options.py b/src/lisflood/global_modules/default_options.py index fe6f02f7..d3a955c9 100644 --- a/src/lisflood/global_modules/default_options.py +++ b/src/lisflood/global_modules/default_options.py @@ -982,18 +982,18 @@ 'TaOtherMaps': ReportedMap(name='TaOtherMaps', output_var='Ta[0]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.6e-4, add_offset=15.0), + yearly=False, scale_factor=3.4e-4, add_offset=9.0), 'TaForestMaps': ReportedMap(name='TaForestMaps', output_var='Ta[1]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.6e-4, add_offset=15.0), + yearly=False, scale_factor=3.4e-4, add_offset=9.0), 'TaIrrigationMaps': ReportedMap(name='TaIrrigationMaps', output_var='Ta[2]', unit='mm', end=[], steps=[], all=['repTaMaps'], restrictoption=['nonInit'], monthly=False, - yearly=False, scale_factor=4.6e-4, add_offset=15.0), + yearly=False, scale_factor=3.4e-4, add_offset=9.0), 'TaMaps': ReportedMap(name='TaMaps', output_var='TaPixel', unit='mm', end=[], steps=[], all=['repE2O1','repTaMaps'], restrictoption=['nonInit'], - monthly=False, yearly=False, scale_factor=4.6e-4, add_offset=15.0), + monthly=False, yearly=False, scale_factor=3.4e-4, add_offset=9.0), 'TavgMapsOut': ReportedMap(name='TavgMapsOut', output_var='Tavg', unit='degree', end=[], steps=[], all=['repTavgMaps'], restrictoption=[], monthly=False, yearly=False),