Repository: metno/pyaerocom (language: python)

Issue:
add_maps tries to read min-maximum from model even if min-max is configured in glob_defaults.py
**Describe the bug**
Please provide a clear and concise description of what the bug is.
 - Pyaerocom version: 0.21.0.dev0 and earlier
 - Configuration file (if applicable):
   - any with `add_model_maps=True,` and glob_defaults.py with:
```
"concNno2": {"scale": [0, 0.3, 0.5, 1, 1.3, 1.5, 2, 3, 5], "colmap": "coolwarm"},
```
 - Error message (if applicable):
```
2024-07-08 07:41:57:pyaerocom.aeroval.helpers:279/284M:INFO:re-registering var concNno2 due to: need minimum and maximum to be specified for variable concNno2 in order to retrieve cmap_bins
```

**Expected behavior**
pyaerocom does not read the complete variable to calculate minimum and maximum, which takes quite a while. minimum and maximum are taken directly from "scale"[0] and "scale"[-1]



Discussion / hints:

Fix patch:
diff --git a/docs/_static/aeroval/cfg_examples_example1.py b/docs/_static/aeroval/cfg_examples_example1.py
index e0fed04a5..ab4a19108 100644
--- a/docs/_static/aeroval/cfg_examples_example1.py
+++ b/docs/_static/aeroval/cfg_examples_example1.py
@@ -70,7 +70,7 @@
 Section 1: Global setup for AeroVal output
 ------------------------------------------
 
-The global setup defines: 
+The global setup defines:
 
 - Project and experiment ID
 - Information about the purpose of the experiment and PI
@@ -83,7 +83,7 @@
     - Whether to add seasonal statistics
     - Which regions to use for regional statistics
     - Web display options (e.g. default map zoom)
-    
+
 """
 import os  # needed for specification of path locations below
 
@@ -133,6 +133,10 @@
     # Exponent for NorESM2 model from 440nm and 870nm AOD, which are output
     # by the model.
     io_aux_file=os.path.abspath("../eval_py/gridded_io_aux.py"),
+    # user defined scales and colormaps like https://github.com/metno/pyaerocom/blob/cb01fc8f39fe8b3f63d4ddd858aa63f5f37a6759/pyaerocom/aeroval/data/var_scale_colmap.ini
+    var_scale_colmap_file=os.path.abspath("./var_scale_colmap.ini"),
+    # user defined variable names like https://github.com/metno/pyaerocom/blob/10cb76ce388ffc5c43f3f8e86f6dda81b594fb7d/pyaerocom/aeroval/data/var_web_info.ini
+    var_web_info_file=os.path.abspath("./var_web_info.ini"),
     # Frequencies for which statistical parameters are computed
     freqs=["daily", "monthly", "yearly"],
     # Main output frequency for AeroVal (some of the AeroVal processing
@@ -212,16 +216,16 @@
 Section 3: Configuration of observations
 ----------------------------------------
 
-Each obs entry needs at least an obs ID specified, a list of variables 
-that are supposed to be analysed and a specification of the vertical type  
-of the data (e.g. Column, Surface). 
-You may search for observational data via the pyaerocom CLI. E.g. to search 
-for observations containing the strings "Aeronet" and "Sun" and "V3" you may 
+Each obs entry needs at least an obs ID specified, a list of variables
+that are supposed to be analysed and a specification of the vertical type
+of the data (e.g. Column, Surface).
+You may search for observational data via the pyaerocom CLI. E.g. to search
+for observations containing the strings "Aeronet" and "Sun" and "V3" you may
 search from the command line via:
 
 pya --browse *Aeronet*Sun*V3*
 
-This will list all data IDs matching this request and will also show 
+This will list all data IDs matching this request and will also show
 variables that are provided by each of the datasets that match the search.
 """
 
@@ -286,9 +290,9 @@
 Section 4: Configuration of models
 ----------------------------------
 
-Each model entry needs at least a model ID specified. If the model data is 
-available in the AeroCom database (in AeroCom file format) you may search 
-for data via the pyaerocom CLI. E.g. to search for model IDs containing 
+Each model entry needs at least a model ID specified. If the model data is
+available in the AeroCom database (in AeroCom file format) you may search
+for data via the pyaerocom CLI. E.g. to search for model IDs containing
 the strings "ECMWF" and "CAMS" you may search from the command line via:
 
 pya --browse *ECMWF*CAMS*
diff --git a/pyaerocom/aeroval/data/var_scale_colmap.ini b/pyaerocom/aeroval/data/var_scale_colmap.ini
new file mode 100644
index 000000000..98df9bea0
--- /dev/null
+++ b/pyaerocom/aeroval/data/var_scale_colmap.ini
@@ -0,0 +1,436 @@
+[default]
+scale = [0.0, 1.25, 2.5, 3.75, 5.0, 6.25, 7.5, 8.75, 10.0]
+colmap = coolwarm
+
+[ang4487aer]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0]
+colmap = coolwarm
+
+[od550aer]
+scale = [0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4]
+colmap = coolwarm
+
+[od550lt1aer]
+scale = [0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4]
+colmap = coolwarm
+
+[od550gt1aer]
+scale = [0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4]
+colmap = coolwarm
+
+[ratpm25pm10]
+scale = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
+colmap = coolwarm
+
+[ratpm10pm25]
+scale = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
+colmap = coolwarm
+
+[od550dust]
+scale = [0.0, 0.0125, 0.025, 0.0375, 0.05, 0.0625, 0.075, 0.0875, 0.1]
+colmap = coolwarm
+
+[abs550aer]
+scale = [0.0, 0.0125, 0.025, 0.0375, 0.05, 0.0625, 0.075, 0.0875, 0.1]
+colmap = coolwarm
+
+[absc550aer]
+scale = [0.0, 12.5, 25.0, 37.5, 50.0, 62.5, 75.0, 87.5, 100.0]
+colmap = coolwarm
+
+[scatc550dryaer]
+scale = [0.0, 12.5, 25.0, 37.5, 50.0, 62.5, 75.0, 87.5, 100.0]
+colmap = coolwarm
+
+[extinction]
+scale = [0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0]
+colmap = coolwarm
+
+[ssa670aer]
+scale = [0.75, 0.775, 0.8, 0.825, 0.85, 0.875, 0.9, 0.925, 0.95, 0.975, 1.0]
+colmap = coolwarm
+
+[backscatter]
+scale = [0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0]
+colmap = coolwarm
+
+[concso4]
+scale = [0.0, 0.75, 1.5, 2.25, 3.0, 3.75, 4.5, 5.25, 6.0, 6.75, 7.5, 8.25]
+colmap = coolwarm
+
+[concso2]
+scale = [0.0, 0.75, 1.5, 2.25, 3.0, 3.75, 4.5, 5.25, 6.0, 6.75, 7.5, 8.25]
+colmap = coolwarm
+
+[vmrno]
+scale = [0.0, 0.75, 1.5, 2.25, 3.0, 3.75, 4.5, 5.25, 6.0, 6.75, 7.5, 8.25]
+colmap = coolwarm
+
+[vmrso2]
+scale = [0.0, 0.75, 1.5, 2.25, 3.0, 3.75, 4.5, 5.25, 6.0, 6.75, 7.5, 8.25]
+colmap = coolwarm
+
+[concpm10]
+scale = [0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0]
+colmap = coolwarm
+
+[concpm25]
+scale = [0.0, 5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0]
+colmap = coolwarm
+
+[conco3]
+scale = [0.0, 15.0, 30.0, 45.0, 60.0, 75.0, 90.0, 105.0, 120.0]
+colmap = coolwarm
+
+[vmro3]
+scale = [20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0, 55.0, 60.0, 65.0, 70.0]
+colmap = coolwarm
+
+[vmrox]
+scale = [20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0, 55.0, 60.0, 65.0, 70.0]
+colmap = coolwarm
+
+[concno2]
+scale = [0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0]
+colmap = coolwarm
+
+[concNno2]
+scale = [0.0, 0.3, 0.5, 1.0, 1.3, 1.5, 2.0, 3.0, 5.0]
+colmap = coolwarm
+
+[vmrno2]
+scale = [0.0, 5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0]
+colmap = coolwarm
+
+[vmro3max]
+scale = [0.0, 7.5, 15.0, 22.5, 30.0, 37.5, 45.0, 52.5, 60.0]
+colmap = coolwarm
+
+[vmro3mda8]
+scale = [20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0, 55.0, 60.0, 65.0, 70.0]
+colmap = coolwarm
+
+[concNhno3]
+scale = [0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 1.0]
+colmap = coolwarm
+
+[concNno3pm10]
+scale = [0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0, 1.5, 2.0, 5.0, 10.0]
+colmap = coolwarm
+
+[concNno3pm25]
+scale = [0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0, 1.5, 2.0, 5.0, 10.0]
+colmap = coolwarm
+
+[concNnh3]
+scale = [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 7.5, 10.0, 20.0]
+colmap = coolwarm
+
+[concNnh4]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0]
+colmap = coolwarm
+
+[concNtno3]
+scale = [0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0, 1.5, 2.0, 5.0]
+colmap = coolwarm
+
+[concNtnh]
+scale = [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 7.5, 10.0, 20.0, 50.0]
+colmap = coolwarm
+
+[concsspm25]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 5.0, 10.0]
+colmap = coolwarm
+
+[concsspm10]
+scale = [0.0, 0.75, 1.5, 2.25, 3.0, 3.75, 4.5, 5.25, 6.0, 6.75, 7.5, 8.25, 10.0, 15.0, 20.0, 50.0]
+colmap = coolwarm
+
+[concCecpm25]
+scale = [0.0, 1.25, 2.5, 3.75, 5.0, 6.25, 7.5, 8.75, 10.0]
+colmap = coolwarm
+
+[concCec25]
+scale = [0.0, 1.25, 2.5, 3.75, 5.0, 6.25, 7.5, 8.75, 10.0]
+colmap = coolwarm
+
+[concCocpm25]
+scale = [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 10.0]
+colmap = coolwarm
+
+[concCoc25]
+scale = [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 10.0]
+colmap = coolwarm
+
+[concom25]
+scale = [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0]
+colmap = coolwarm
+
+[wetoxs]
+scale = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1.0, 1.5, 2.0, 5.0]
+colmap = coolwarm
+
+[wetna]
+scale = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1.0, 1.5, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0]
+colmap = coolwarm
+
+[wetoxn]
+scale = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1.0, 1.5, 2.0, 5.0]
+colmap = coolwarm
+
+[wetrdn]
+scale = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1.0, 1.5, 2.0, 5.0, 10.0]
+colmap = coolwarm
+
+[wetoxsf]
+scale = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1.0, 1.5, 2.0, 5.0]
+colmap = coolwarm
+
+[wetoxnf]
+scale = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1.0, 1.5, 2.0, 5.0]
+colmap = coolwarm
+
+[wetrdnf]
+scale = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1.0, 1.5, 2.0, 5.0, 10.0]
+colmap = coolwarm
+
+[prmm]
+scale = [0.0, 1.25, 2.5, 3.75, 5.0, 6.25, 7.5, 8.75, 10.0]
+colmap = coolwarm
+
+[dryoxs]
+scale = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1.0, 1.5, 2.0, 5.0]
+colmap = coolwarm
+
+[dryoxn]
+scale = [0.0, 0.1, 0.2, 0.5, 1.0, 2.0, 5.0, 10.0, 20.0, 50.0]
+colmap = coolwarm
+
+[dryrdn]
+scale = [0.0, 0.1, 0.2, 0.5, 1.0, 2.0, 5.0, 10.0, 20.0, 50.0]
+colmap = coolwarm
+
+[depdust]
+scale = [0.01, 0.2, 0.5, 1.0, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0, 200.0, 500.0, 1000.0]
+colmap = coolwarm
+
+[drydust]
+scale = [0.0, 0.2, 0.5, 1.0, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0, 200.0, 500.0, 1000.0]
+colmap = coolwarm
+
+[wetdust]
+scale = [0.0, 0.2, 0.5, 1.0, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0, 200.0, 500.0, 1000.0]
+colmap = coolwarm
+
+[concdust]
+scale = [0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0]
+colmap = coolwarm
+
+[vmrco]
+scale = [100.0, 125.0, 150.0, 175.0, 200.0, 225.0, 250.0, 275.0, 300.0]
+colmap = coolwarm
+
+[vmrco2]
+scale = [400.0, 405.0, 410.0, 415.0, 420.0, 425.0, 430.0, 435.0, 440.0, 445.0, 450.0]
+colmap = coolwarm
+
+[vmrch4]
+scale = [1700.0, 1750.0, 1800.0, 1850.0, 1900.0, 1950.0, 2000.0, 2050.0, 2100.0, 2150.0, 2200.0]
+colmap = coolwarm
+
+[concco]
+scale = [100.0, 125.0, 150.0, 175.0, 200.0, 225.0, 250.0, 275.0, 300.0]
+colmap = coolwarm
+
+[ts]
+scale = [265.0, 270.0, 275.0, 280.0, 285.0, 290.0, 300.0, 305.0, 310.0, 315.0, 320.0]
+colmap = coolwarm
+
+[proxyzdust]
+scale = [0.0, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0, 7.5, 10.0]
+colmap = coolwarm
+
+[zdust]
+scale = [0.0, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0, 7.5, 10.0]
+colmap = coolwarm
+
+[proxyzaerosol]
+scale = [0.0, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0, 7.5, 10.0]
+colmap = coolwarm
+
+[zaerosol]
+scale = [0.0, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0, 7.5, 10.0]
+colmap = coolwarm
+
+[proxydryo3]
+scale = [0.0, 0.5, 1.0, 5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 40.0, 50.0]
+colmap = coolwarm
+
+[dryo3]
+scale = [0.0, 0.5, 1.0, 5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 40.0, 50.0]
+colmap = coolwarm
+
+[proxydrypm10]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0]
+colmap = coolwarm
+
+[drypm10]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0]
+colmap = coolwarm
+
+[proxydrypm25]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0]
+colmap = coolwarm
+
+[drypm25]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 5.0, 10.0]
+colmap = coolwarm
+
+[proxydryss]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0]
+colmap = coolwarm
+
+[dryss]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0]
+colmap = coolwarm
+
+[proxydryna]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0, 200.0]
+colmap = coolwarm
+
+[dryna]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0, 200.0]
+colmap = coolwarm
+
+[proxydryno2]
+scale = [0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0, 2.0]
+colmap = coolwarm
+
+[dryno2]
+scale = [0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0, 2.0]
+colmap = coolwarm
+
+[proxydryhono]
+scale = [0.0, 0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.008, 0.01, 0.02]
+colmap = coolwarm
+
+[dryhono]
+scale = [0.0, 0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.008, 0.01, 0.02]
+colmap = coolwarm
+
+[proxydryn2o5]
+scale = [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.2]
+colmap = coolwarm
+
+[dryn2o5]
+scale = [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.2]
+colmap = coolwarm
+
+[proxydryhno3]
+scale = [0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0, 2.0, 5.0]
+colmap = coolwarm
+
+[dryhno3]
+scale = [0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0, 2.0, 5.0]
+colmap = coolwarm
+
+[proxydryno3c]
+scale = [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.5]
+colmap = coolwarm
+
+[dryno3c]
+scale = [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.5]
+colmap = coolwarm
+
+[proxydryno3f]
+scale = [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.5]
+colmap = coolwarm
+
+[dryno3f]
+scale = [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.5]
+colmap = coolwarm
+
+[proxydrynh3]
+scale = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1.0, 2.0, 5.0]
+colmap = coolwarm
+
+[drynh3]
+scale = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1.0, 2.0, 5.0]
+colmap = coolwarm
+
+[proxydrynh4]
+scale = [0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0]
+colmap = coolwarm
+
+[drynh4]
+scale = [0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0]
+colmap = coolwarm
+
+[proxydryso2]
+scale = [0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0, 2.0, 5.0]
+colmap = coolwarm
+
+[dryso2]
+scale = [0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0, 2.0, 5.0]
+colmap = coolwarm
+
+[proxydryso4]
+scale = [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.2, 0.5]
+colmap = coolwarm
+
+[dryso4]
+scale = [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.2, 0.5]
+colmap = coolwarm
+
+[proxydryoxs]
+scale = [0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4]
+colmap = coolwarm
+
+[proxydryoxn]
+scale = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]
+colmap = coolwarm
+
+[proxydryrdn]
+scale = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]
+colmap = coolwarm
+
+[depoxs]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 5.0, 10.0, 20.0]
+colmap = coolwarm
+
+[depna]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0, 200.0]
+colmap = coolwarm
+
+[depoxn]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 5.0, 10.0, 20.0]
+colmap = coolwarm
+
+[deprdn]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0, 200.0]
+colmap = coolwarm
+
+[depoxsf]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 5.0, 10.0, 20.0]
+colmap = coolwarm
+
+[depnaf]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 5.0, 10.0, 20.0]
+colmap = coolwarm
+
+[depoxnf]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 5.0, 10.0, 20.0]
+colmap = coolwarm
+
+[deprdnf]
+scale = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0, 200.0]
+colmap = coolwarm
+
+[bsc532aer]
+scale = [0.0, 0.0005, 0.001, 0.0015, 0.002, 0.0025, 0.003, 0.0035, 0.004]
+colmap = coolwarm
+
+[ec532aer]
+scale = [0.0, 0.004, 0.008, 0.012, 0.016, 0.02, 0.04, 0.06, 0.08, 0.1, 0.2, 0.3, 0.4]
+colmap = coolwarm
+
diff --git a/pyaerocom/aeroval/data/var_web_info.ini b/pyaerocom/aeroval/data/var_web_info.ini
new file mode 100644
index 000000000..5c0311e00
--- /dev/null
+++ b/pyaerocom/aeroval/data/var_web_info.ini
@@ -0,0 +1,799 @@
+# variable information used for the aeroval web-interface
+
+[od550aer]
+menu_name = AOD
+vertical_type = 2D
+category = Optical properties
+
+[od550csaer]
+menu_name = AOD (clear sky)
+vertical_type = 2D
+category = Optical properties
+
+[od550lt1aer]
+menu_name = AODf
+vertical_type = 2D
+category = Optical properties
+
+[od550gt1aer]
+menu_name = AODc
+vertical_type = 2D
+category = Optical properties
+
+[od550dust]
+menu_name = AODdust
+vertical_type = 2D
+category = Optical properties
+
+[abs550aer]
+menu_name = AAOD
+vertical_type = 2D
+category = Optical properties
+
+[ssa670aer]
+menu_name = SSA
+vertical_type = 2D
+category = Optical properties
+
+[ang4487aer]
+menu_name = AE
+vertical_type = 2D
+category = Optical properties
+
+[angabs4487aer]
+menu_name = AAE
+vertical_type = 2D
+category = Optical properties
+
+[ang4487csaer]
+menu_name = AE (clear sky)
+vertical_type = 2D
+category = Optical properties
+
+[sc550dryaer]
+menu_name = Scat. coef. (dry)
+vertical_type = 3D
+category = Optical properties
+
+[sc550aer]
+menu_name = Scat. coef.
+vertical_type = 3D
+category = Optical properties
+
+[ac550aer]
+menu_name = Abs. coef.
+vertical_type = 3D
+category = Optical properties
+
+[ac550dryaer]
+menu_name = Abs. coef. (dry)
+vertical_type = 3D
+category = Optical properties
+
+[ec532aer]
+menu_name = Ext. coeff.
+vertical_type = 3D
+category = Optical properties
+
+[bsc532aer]
+menu_name = Backscat. coeff.
+vertical_type = 3D
+category = Optical properties
+
+[concso4pr]
+menu_name = SO4 (precip.)
+vertical_type = 3D
+category = Particle concentrations
+
+[concbc]
+menu_name = BC
+vertical_type = 3D
+category = Particle concentrations
+
+[concoa]
+menu_name = OA
+vertical_type = 3D
+category = Particle concentrations
+
+[concss]
+menu_name = SS
+vertical_type = 3D
+category = Particle concentrations
+
+[conco3]
+menu_name = O3
+vertical_type = 3D
+category = Gas concentrations
+
+[concno310]
+menu_name = NO3_PM10
+vertical_type = 3D
+category = Particle concentrations
+
+[concno325]
+menu_name = NO3_PM25
+vertical_type = 3D
+category = Particle concentrations
+
+[proxyod550bc]
+menu_name = OD (Black Carbon)
+vertical_type = 2D
+category = Optical properties
+
+[proxyod550dust]
+menu_name = OD (Dust)
+vertical_type = 2D
+category = Optical properties
+
+[proxyod550oa]
+menu_name = OD (Organic Matter)
+vertical_type = 2D
+category = Optical properties
+
+[proxyod550so4]
+menu_name = OD (SO4)
+vertical_type = 2D
+category = Optical properties
+
+[proxyod550ss]
+menu_name = OD (Sea Salt)
+vertical_type = 2D
+category = Optical properties
+
+[proxyod550nh4]
+menu_name = OD (NH4)
+vertical_type = 2D
+category = Optical properties
+
+[proxyod550no3]
+menu_name = OD (NO3)
+vertical_type = 2D
+category = Optical properties
+
+[proxyzdust]
+menu_name = DLH
+vertical_type = 2D
+category = Height
+
+[zdust]
+menu_name = DLH
+vertical_type = 2D
+category = Height
+
+[proxyzaerosol]
+menu_name = ALH
+vertical_type = 2D
+category = Height
+
+[zaerosol]
+menu_name = ALH
+vertical_type = 2D
+category = Height
+
+# Gases
+
+[concNno]
+menu_name = NO
+vertical_type = 3D
+category = Concentration
+
+[concno2]
+menu_name = NO2
+vertical_type = 3D
+category = Gas concentrations
+
+[concNno2]
+menu_name = NO2
+vertical_type = 3D
+category = Gas concentrations
+
+[vmrno]
+menu_name = NO
+vertical_type = 3D
+category = Volume mixing ratios
+
+[vmrno2]
+menu_name = NO2
+vertical_type = 3D
+category = Volume mixing ratios
+
+[concno3]
+menu_name = NO3
+vertical_type = 3D
+category = Gas concentrations
+
+[conctno3]
+menu_name = tNO3
+vertical_type = 3D
+category = Concentration
+
+[concNtno3]
+menu_name = tNO3
+vertical_type = 3D
+category = Concentration
+
+[conchno3]
+menu_name = HNO3
+vertical_type = 3D
+category = Concentration
+
+[concNhno3]
+menu_name = HNO3
+vertical_type = 3D
+category = Concentration
+
+[concnh3]
+menu_name = NH3
+vertical_type = 3D
+category = Concentration
+
+[concNnh3]
+menu_name = NH3
+vertical_type = 3D
+category = Concentration
+
+[conctnh]
+menu_name = tNH
+vertical_type = 3D
+category = Concentration
+
+[concNtnh]
+menu_name = tNH
+vertical_type = 3D
+category = Concentration
+
+[concnh4]
+menu_name = NH4
+vertical_type = 3D
+category = Gas concentrations
+
+[concNnh4]
+menu_name = NH4
+vertical_type = 3D
+category = Gas concentrations
+
+[concso2]
+menu_name = SO2
+vertical_type = 3D
+category = Gas concentrations
+
+[concSso2]
+menu_name = SO2
+vertical_type = 3D
+category = Gas concentrations
+
+[vmrso2]
+menu_name = SO2
+vertical_type = 3D
+category = Gas volume mixing ratio
+
+[concso4]
+menu_name = SO4
+vertical_type = 3D
+category = Particle concentrations
+
+[vmro3]
+menu_name = O3
+vertical_type = 3D
+category = Volume mixing ratios
+
+[vmro3mda8]
+menu_name = O3 MDA8
+vertical_type = 3D
+category = Volume mixing ratios
+
+[vmro3max]
+menu_name = O3Max
+vertical_type = 3D
+category = Volume mixing ratios
+
+[vmrox]
+menu_name = OX
+vertical_type = 3D
+category = Gas volume mixing ratio
+
+[concco]
+menu_name = CO
+vertical_type = 3D
+category = Particle concentrations
+
+[vmrco]
+menu_name = CO
+vertical_type = 3D
+category = Volume mixing ratios
+
+[vmrco2]
+menu_name = CO2
+vertical_type = 3D
+category = Volume mixing ratios
+
+[vmrc2h2]
+menu_name = Ethyne
+vertical_type = 3D
+category = Volume mixing ratios
+
+[vmrc2h4]
+menu_name = Ethylene
+vertical_type = 3D
+category = Volume mixing ratios
+
+[vmrc2h6]
+menu_name = Ethane
+vertical_type = 3D
+category = Volume mixing ratios
+
+[vmrhcho]
+menu_name = Formaldehyde
+vertical_type = 3D
+category = Volume mixing ratios
+
+[vmrisop]
+menu_name = Isoprene
+vertical_type = 3D
+category = Volume mixing ratios
+
+[vmrch4]
+menu_name = CH4
+vertical_type = 3D
+category = Volume mixing ratios
+
+# PMs
+
+[concpm10]
+menu_name = PM10
+vertical_type = 3D
+category = Particle concentrations
+
+[concpm10pbap]
+menu_name = PM10 PBAP
+vertical_type = 3D
+category = Particle concentrations
+
+[concpm25]
+menu_name = PM2.5
+vertical_type = 3D
+category = Particle concentrations
+
+[concNno3pm10]
+menu_name = NO3 PM10
+vertical_type = 3D
+category = Particle concentrations
+
+[concNno3pm25]
+menu_name = NO3 PM25
+vertical_type = 3D
+category = Particle concentrations
+
+[concno3pm10]
+menu_name = NO3 PM10
+vertical_type = 3D
+category = Particle concentrations
+
+[concno3pm25]
+menu_name = NO3 PM25
+vertical_type = 3D
+category = Particle concentrations
+
+[concnh4coarse]
+menu_name = NH4 PM10
+vertical_type = 3D
+category = Particle concentrations
+
+[concnh4fine]
+menu_name = NH4 PM2.5
+vertical_type = 3D
+category = Particle concentrations
+
+[concso4t]
+menu_name = SO4 total
+vertical_type = 3D
+category = Particle concentrations
+
+[concso4c]
+menu_name = SO4 sea salt corrected
+vertical_type = 3D
+category = Particle concentrations
+
+[concso4coarse]
+menu_name = SO4 PM10
+vertical_type = 3D
+category = Particle concentrations
+
+[concso4fine]
+menu_name = SO4 PM2.5
+vertical_type = 3D
+category = Particle concentrations
+
+[concss10]
+menu_name = SS PM10
+vertical_type = 3D
+category = Particle concentrations
+
+[concss25]
+menu_name = SS PM25
+vertical_type = 3D
+category = Particle concentrations
+
+[concec]
+menu_name = EC
+vertical_type = 3D
+category = Particle concentrations
+
+[conccoc]
+menu_name = OC
+vertical_type = 3D
+category = Particle concentrations
+
+[concsspm10]
+menu_name = SS PM10
+vertical_type = 3D
+category = Particle concentrations
+
+[concsspm25]
+menu_name = SS PM25
+vertical_type = 3D
+category = Particle concentrations
+
+[concCecpm25]
+menu_name = EC PM2.5
+vertical_type = 3D
+category = Particle concentrations
+
+[concCocpm25]
+menu_name = OC PM2.5
+vertical_type = 3D
+category = Particle concentrations
+
+[concCec25]
+menu_name = EC PM2.5
+vertical_type = 3D
+category = Particle concentrations
+
+[concCoc25]
+menu_name = OC PM2.5
+vertical_type = 3D
+category = Particle concentrations
+
+[concom25]
+menu_name = OM PM2.5
+vertical_type = 3D
+category = Particle concentrations
+
+[concCecpm10]
+menu_name = EC PM10
+vertical_type = 3D
+category = Particle concentrations
+
+[concCocpm10]
+menu_name = OC PM10
+vertical_type = 3D
+category = Particle concentrations
+
+[concdust]
+menu_name = Dust concentration
+vertical_type = 3D
+category = Particle concentrations
+
+# Depositions
+
+[depoxs]
+menu_name = TotDepOXS
+vertical_type = 3D
+category = Deposition
+
+[deprdn]
+menu_name = TotDepRDN
+vertical_type = 3D
+category = Deposition
+
+[depoxn]
+menu_name = TotDepOXN
+vertical_type = 3D
+category = Deposition
+
+[depoxsf]
+menu_name = TotDepOXSforr
+vertical_type = 3D
+category = Deposition
+
+[deprdnf]
+menu_name = TotDepRDNforr
+vertical_type = 3D
+category = Deposition
+
+[depoxnf]
+menu_name = TotDepOXNforr
+vertical_type = 3D
+category = Deposition
+
+[depss]
+menu_name = TotDepSS
+vertical_type = 3D
+category = Deposition
+
+[depssf]
+menu_name = TotDepSSforr
+vertical_type = 3D
+category = Deposition
+
+[depna]
+menu_name = TotDepNa
+vertical_type = 3D
+category = Deposition
+
+[depnaf]
+menu_name = TotDepNaforr
+vertical_type = 3D
+category = Deposition
+
+[drysox]
+menu_name = DryOXS
+vertical_type = 3D
+category = Deposition
+
+[dryoxs]
+menu_name = DryOXS
+vertical_type = 3D
+category = Deposition
+
+[dryoxn]
+menu_name = DryOXN
+vertical_type = 3D
+category = Deposition
+
+[dryrdn]
+menu_name = DryRDN
+vertical_type = 3D
+category = Deposition
+
+[depdust]
+menu_name = TotDustDep
+vertical_type = 3D
+category = Deposition
+
+[drydust]
+menu_name = DryDustDep
+vertical_type = 3D
+category = Deposition
+
+[wetdust]
+menu_name = WetDustDep
+vertical_type = 3D
+category = Deposition
+
+[wetoxs]
+menu_name = WetOXS
+vertical_type = 3D
+category = Deposition
+
+[wetna]
+menu_name = WetNa
+vertical_type = 3D
+category = Deposition
+
+[wetoxsc]
+menu_name = WetOXScorr
+vertical_type = 3D
+category = Deposition
+
+[wetoxst]
+menu_name = WetOXStot
+vertical_type = 3D
+category = Deposition
+
+[wetoxn]
+menu_name = WetOXN
+vertical_type = 3D
+category = Deposition
+
+[wetrdn]
+menu_name = WetRDN
+vertical_type = 3D
+category = Deposition
+
+[prmm]
+menu_name = Precipitation
+vertical_type = 3D
+category = Deposition
+
+# Temperature
+
+[ts]
+menu_name = Surface Temperature
+vertical_type = 3D
+category = Temperature
+
+# proxy drydep
+
+[proxydryoxs]
+menu_name = proxyDryOXS
+vertical_type = 3D
+category = Deposition
+
+[proxydryss]
+menu_name = proxyDrySS
+vertical_type = 3D
+category = Deposition
+
+[proxydryna]
+menu_name = proxyDryNa
+vertical_type = 3D
+category = Deposition
+
+[proxydryso2]
+menu_name = proxyDrySO2
+vertical_type = 3D
+category = Deposition
+
+[proxydryso4]
+menu_name = proxyDrySO4
+vertical_type = 3D
+category = Deposition
+
+[proxydryoxn]
+menu_name = proxyDryOXN
+vertical_type = 3D
+category = Deposition
+
+[proxydryno2]
+menu_name = proxyDryNO2
+vertical_type = 3D
+category = Deposition
+
+[proxydryno2no2]
+menu_name = proxyDryNO2NO2
+vertical_type = 3D
+category = Deposition
+
+[proxydryhono]
+menu_name = proxyDryHONO
+vertical_type = 3D
+category = Deposition
+
+[proxydryn2o5]
+menu_name = proxyDryN2O5
+vertical_type = 3D
+category = Deposition
+
+[proxydryhno3]
+menu_name = proxyDryHNO3
+vertical_type = 3D
+category = Deposition
+
+[proxydryno3c]
+menu_name = proxyDryNO3Coarse
+vertical_type = 3D
+category = Deposition
+
+[proxydryno3f]
+menu_name = proxyDryNO3Fine
+vertical_type = 3D
+category = Deposition
+
+[proxydryrdn]
+menu_name = proxyDryRDN
+vertical_type = 3D
+category = Deposition
+
+[proxydrynh3]
+menu_name = proxyDryNH3
+vertical_type = 3D
+category = Deposition
+
+[proxydrynh4]
+menu_name = proxyDryNH4
+vertical_type = 3D
+category = Deposition
+
+[proxydryo3]
+menu_name = proxyDryO3
+vertical_type = 3D
+category = Deposition
+
+[proxydrypm10]
+menu_name = proxyDryPM10
+vertical_type = 3D
+category = Deposition
+
+[proxydrypm25]
+menu_name = proxyDryPM2.5
+vertical_type = 3D
+category = Deposition
+
+[proxywetoxs]
+menu_name = proxyWetOXS
+vertical_type = 3D
+category = Deposition
+
+[proxywetso2]
+menu_name = proxyWetSO2
+vertical_type = 3D
+category = Deposition
+
+[proxywetso4]
+menu_name = proxyWetSO4
+vertical_type = 3D
+category = Deposition
+
+[proxywetoxn]
+menu_name = proxyWetOXN
+vertical_type = 3D
+category = Deposition
+
+[proxywetno2]
+menu_name = proxyWetNO2
+vertical_type = 3D
+category = Deposition
+
+[proxywetno2no2]
+menu_name = proxyWetNO2NO2
+vertical_type = 3D
+category = Deposition
+
+[proxywethono]
+menu_name = proxyWetHONO
+vertical_type = 3D
+category = Deposition
+
+[proxywetn2o5]
+menu_name = proxyWetN2O5
+vertical_type = 3D
+category = Deposition
+
+[proxywethno3]
+menu_name = proxyWetHNO3
+vertical_type = 3D
+category = Deposition
+
+[proxywetno3c]
+menu_name = proxyWetNO3Coarse
+vertical_type = 3D
+category = Deposition
+
+[proxywetno3f]
+menu_name = proxyWetNO3Fine
+vertical_type = 3D
+category = Deposition
+
+[proxywetrdn]
+menu_name = proxyWetRDN
+vertical_type = 3D
+category = Deposition
+
+[proxywetnh3]
+menu_name = proxyWetNH3
+vertical_type = 3D
+category = Deposition
+
+[proxywetnh4]
+menu_name = proxyWetNH4
+vertical_type = 3D
+category = Deposition
+
+[proxyweto3]
+menu_name = proxyWetO3
+vertical_type = 3D
+category = Deposition
+
+[proxywetpm10]
+menu_name = proxyWetPM10
+vertical_type = 3D
+category = Deposition
+
+[proxywetpm25]
+menu_name = proxyWetPM2.5
+vertical_type = 3D
+category = Deposition
+
+# other stuff
+
+[ratpm25pm10]
+menu_name = ratio PM2.5 PM10
+vertical_type = 3D
+category = Particle ratio
+
+[ratpm10pm25]
+menu_name = ratio PM10 PM2.5
+vertical_type = 3D
+category = Particle ratio
+
diff --git a/pyaerocom/aeroval/experiment_output.py b/pyaerocom/aeroval/experiment_output.py
index cffdab848..a8ec8981f 100644
--- a/pyaerocom/aeroval/experiment_output.py
+++ b/pyaerocom/aeroval/experiment_output.py
@@ -8,13 +8,12 @@
 from pyaerocom._lowlevel_helpers import DirLoc, StrType, TypeValidator, sort_dict_by_name
 from pyaerocom.aeroval.collections import ObsCollection
 from pyaerocom.aeroval.glob_defaults import (
+    VariableInfo,
     extended_statistics,
     statistics_defaults,
     statistics_model_only,
     statistics_obs_only,
     statistics_trend,
-    var_ranges_defaults,
-    var_web_info,
 )
 from pyaerocom.aeroval.json_utils import check_make_json, read_json, write_json
 from pyaerocom.aeroval.modelentry import ModelEntry
@@ -29,8 +28,6 @@
     "MapInfo", ["obs_network", "obs_var", "vert_code", "mod_name", "mod_var", "time_period"]
 )
 
-VariableInfo = namedtuple("VariableInfo", ["menu_name", "vertical_type", "category"])
-
 logger = logging.getLogger(__name__)
 
 
@@ -508,7 +505,8 @@ def _get_json_output_files(self, dirname) -> list[str]:
         dirloc = self.out_dirs_json[dirname]
         return glob.glob(f"{dirloc}/*.json")
 
-    def _get_cmap_info(self, var) -> list[float]:
+    def _get_cmap_info(self, var) -> dict[str, str | list[float]]:
+        var_ranges_defaults = self.cfg.var_scale_colmap
         if var in var_ranges_defaults:
             return var_ranges_defaults[var]
         try:
@@ -581,8 +579,8 @@ def _get_var_name_and_type(self, var_name: str) -> VariableInfo:
             - Vertical type of this variable (ie. 2D, 3D).
             - Category of this variable.
         """
-        if var_name in var_web_info:
-            name, tp, cat = var_web_info[var_name]
+        if var_name in self.cfg.var_web_info:
+            name, tp, cat = self.cfg.var_web_info[var_name]
         else:
             name, tp, cat = var_name, "UNDEFINED", "UNDEFINED"
             logger.warning(f"Missing menu name definition for var {var_name}.")
diff --git a/pyaerocom/aeroval/glob_defaults.py b/pyaerocom/aeroval/glob_defaults.py
index 28c1d87d5..2dcb49c61 100644
--- a/pyaerocom/aeroval/glob_defaults.py
+++ b/pyaerocom/aeroval/glob_defaults.py
@@ -1,367 +1,212 @@
 #: Default variable ranges for web display
-var_ranges_defaults = {
-    "default": {"scale": [0, 1.25, 2.5, 3.75, 5, 6.25, 7.5, 8.75, 10], "colmap": "coolwarm"},
-    "ang4487aer": {
-        "scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],
-        "colmap": "coolwarm",
-    },
-    "od550aer": {
-        "scale": [0, 0.05, 0.1, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40],
-        "colmap": "coolwarm",
-    },
-    "od550lt1aer": {
-        "scale": [0, 0.05, 0.1, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40],
-        "colmap": "coolwarm",
-    },
-    "od550gt1aer": {
-        "scale": [0, 0.05, 0.1, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40],
-        "colmap": "coolwarm",
-    },
-    "ratpm25pm10": {
-        "scale": [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0],
-        "colmap": "coolwarm",
-    },
-    "ratpm10pm25": {
-        "scale": [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0],
-        "colmap": "coolwarm",
-    },
-    "od550dust": {
-        "scale": [0, 0.0125, 0.025, 0.0375, 0.05, 0.0625, 0.075, 0.0875, 0.1],
-        "colmap": "coolwarm",
-    },
-    "abs550aer": {
-        "scale": [0, 0.0125, 0.025, 0.0375, 0.05, 0.0625, 0.075, 0.0875, 0.1],
-        "colmap": "coolwarm",
-    },
-    "absc550aer": {"scale": [0, 12.5, 25, 37.5, 50, 62.5, 75, 87.5, 100], "colmap": "coolwarm"},
-    "scatc550dryaer": {
-        "scale": [0, 12.5, 25, 37.5, 50, 62.5, 75, 87.5, 100],
-        "colmap": "coolwarm",
-    },
-    "extinction": {
-        "scale": [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1],
-        "colmap": "coolwarm",
-    },
-    "ssa670aer": {
-        "scale": [0.75, 0.775, 0.8, 0.825, 0.85, 0.875, 0.9, 0.925, 0.95, 0.975, 1],
-        "colmap": "coolwarm",
-    },
-    "backscatter": {
-        "scale": [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1],
-        "colmap": "coolwarm",
-    },
-    "concso4": {
-        "scale": [0, 0.75, 1.5, 2.25, 3.0, 3.75, 4.5, 5.25, 6.0, 6.75, 7.5, 8.25],
-        "colmap": "coolwarm",
-    },
-    "concso2": {
-        "scale": [0, 0.75, 1.5, 2.25, 3.0, 3.75, 4.5, 5.25, 6.0, 6.75, 7.5, 8.25],
-        "colmap": "coolwarm",
-    },
-    "vmrno": {
-        "scale": [0, 0.75, 1.5, 2.25, 3.0, 3.75, 4.5, 5.25, 6.0, 6.75, 7.5, 8.25],
-        "colmap": "coolwarm",
-    },
-    "vmrso2": {
-        "scale": [0, 0.75, 1.5, 2.25, 3.0, 3.75, 4.5, 5.25, 6.0, 6.75, 7.5, 8.25],
-        "colmap": "coolwarm",
-    },
-    "concpm10": {"scale": [0, 10, 20, 30, 40, 50, 60, 70, 80], "colmap": "coolwarm"},
-    "concpm25": {"scale": [0, 5, 10, 15, 20, 25, 30, 35, 40, 45], "colmap": "coolwarm"},
-    "conco3": {"scale": [0, 15, 30, 45, 60, 75, 90, 105, 120], "colmap": "coolwarm"},
-    "vmro3": {"scale": [20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70], "colmap": "coolwarm"},
-    "vmrox": {"scale": [20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70], "colmap": "coolwarm"},
-    "concno2": {"scale": [0, 10, 20, 30, 40, 50, 60, 70, 80], "colmap": "coolwarm"},
-    "concNno2": {"scale": [0, 0.3, 0.5, 1, 1.3, 1.5, 2, 3, 5], "colmap": "coolwarm"},
-    "vmrno2": {"scale": [0, 5, 10, 15, 20, 25, 30, 35, 40], "colmap": "coolwarm"},
-    "vmro3max": {"scale": [0, 7.5, 15, 22.5, 30, 37.5, 45, 52.5, 60], "colmap": "coolwarm"},
-    "concNhno3": {
-        "scale": [0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 1],
-        "colmap": "coolwarm",
-    },
-    "concNno3pm10": {
-        "scale": [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1, 1.5, 2, 5, 10],
-        "colmap": "coolwarm",
-    },
-    "concNno3pm25": {
-        "scale": [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1, 1.5, 2, 5, 10],
-        "colmap": "coolwarm",
-    },
-    "concNnh3": {
-        "scale": [0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 7.5, 10.0, 20],
-        "colmap": "coolwarm",
-    },
-    "concNnh4": {
-        "scale": [0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0],
-        "colmap": "coolwarm",
-    },
-    "concNtno3": {
-        "scale": [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0, 1.5, 2, 5],
-        "colmap": "coolwarm",
-    },
-    "concNtnh": {
-        "scale": [0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 7.5, 10.0, 20, 50],
-        "colmap": "coolwarm",
-    },
-    "concsspm25": {
-        "scale": [0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 5, 10],
-        "colmap": "coolwarm",
-    },
-    "concsspm10": {
-        "scale": [0, 0.75, 1.5, 2.25, 3.0, 3.75, 4.5, 5.25, 6.0, 6.75, 7.5, 8.25, 10, 15, 20, 50],
-        "colmap": "coolwarm",
-    },
-    "concCecpm25": {"scale": [0, 1.25, 2.5, 3.75, 5, 6.25, 7.5, 8.75, 10], "colmap": "coolwarm"},
-    "concCec25": {"scale": [0, 1.25, 2.5, 3.75, 5, 6.25, 7.5, 8.75, 10], "colmap": "coolwarm"},
-    "concCocpm25": {
-        "scale": [0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 10],
-        "colmap": "coolwarm",
-    },
-    "concCoc25": {
-        "scale": [0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 10],
-        "colmap": "coolwarm",
-    },
-    "concom25": {
-        "scale": [0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0],
-        "colmap": "coolwarm",
-    },
-    "wetoxs": {"scale": [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1, 1.5, 2, 5], "colmap": "coolwarm"},
-    "wetna": {
-        "scale": [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1, 1.5, 2, 5, 10, 20, 50, 100],
-        "colmap": "coolwarm",
-    },
-    "wetoxn": {"scale": [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1, 1.5, 2, 5], "colmap": "coolwarm"},
-    "wetrdn": {
-        "scale": [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1, 1.5, 2, 5, 10],
-        "colmap": "coolwarm",
-    },
-    "wetoxsf": {"scale": [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1, 1.5, 2, 5], "colmap": "coolwarm"},
-    "wetoxnf": {"scale": [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1, 1.5, 2, 5], "colmap": "coolwarm"},
-    "wetrdnf": {
-        "scale": [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1, 1.5, 2, 5, 10],
-        "colmap": "coolwarm",
-    },
-    "prmm": {"scale": [0, 1.25, 2.5, 3.75, 5, 6.25, 7.5, 8.75, 10], "colmap": "coolwarm"},
-    "dryoxs": {
-        "scale": [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1, 1.5, 2, 5],
-        "colmap": "coolwarm",
-    },
-    "dryoxn": {"scale": [0, 0.1, 0.2, 0.5, 1, 2.0, 5, 10, 20, 50], "colmap": "coolwarm"},
-    "dryrdn": {"scale": [0, 0.1, 0.2, 0.5, 1, 2.0, 5, 10, 20, 50], "colmap": "coolwarm"},
-    "depdust": {
-        "scale": [0.01, 0.2, 0.5, 1.0, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0, 200.0, 500.0, 1000.0],
-        "colmap": "coolwarm",
-    },
-    "drydust": {
-        # "scale": [0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0],
-        "scale": [0.0, 0.2, 0.5, 1.0, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0, 200.0, 500.0, 1000.0],
-        "colmap": "coolwarm",
-    },
-    "wetdust": {
-        "scale": [0.0, 0.2, 0.5, 1.0, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0, 200.0, 500.0, 1000.0],
-        "colmap": "coolwarm",
-    },
-    "concdust": {
-        "scale": [0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0],
-        "colmap": "coolwarm",
-    },
-    "vmrco": {
-        "scale": [100.0, 125.0, 150.0, 175.0, 200.0, 225.0, 250.0, 275.0, 300.0],
-        "colmap": "coolwarm",
-    },
-    "vmrco2": {
-        "scale": [400.0, 405.0, 410.0, 415.0, 420.0, 425.0, 430.0, 435.0, 440.0, 445.0, 450.0],
-        "colmap": "coolwarm",
-    },
-    "vmrch4": {
-        "scale": [
-            1700,
-            1750,
-            1800,
-            1850,
-            1900,
-            1950,
-            2000,
-            2050,
-            2100,
-            2150,
-            2200,
-        ],
-        "colmap": "coolwarm",
-    },
-    "concco": {
-        "scale": [100.0, 125.0, 150.0, 175.0, 200.0, 225.0, 250.0, 275.0, 300.0],
-        "colmap": "coolwarm",
-    },
-    "ts": {"scale": [265, 270, 275, 280, 285, 290, 300, 305, 310, 315, 320], "colmap": "coolwarm"},
-    "proxyzdust": {
-        "scale": [0.0, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0, 7.5, 10.0],
-        "colmap": "coolwarm",
-    },
-    "zdust": {
-        "scale": [0.0, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0, 7.5, 10.0],
-        "colmap": "coolwarm",
-    },
-    "proxyzaerosol": {
-        "scale": [0.0, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0, 7.5, 10.0],
-        "colmap": "coolwarm",
-    },
-    "zaerosol": {
-        "scale": [0.0, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0, 7.5, 10.0],
-        "colmap": "coolwarm",
-    },
-    "proxydryo3": {"scale": [0, 0.5, 1, 5, 10, 15, 20, 25, 30, 40, 50], "colmap": "coolwarm"},
-    "dryo3": {"scale": [0, 0.5, 1, 5, 10, 15, 20, 25, 30, 40, 50], "colmap": "coolwarm"},
-    "proxydrypm10": {"scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2], "colmap": "coolwarm"},
-    "drypm10": {
-        "scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 5, 10, 20, 50, 100],
-        "colmap": "coolwarm",
-    },
-    "proxydrypm25": {
-        "scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 5, 10, 20, 50, 100],
-        "colmap": "coolwarm",
-    },
-    "drypm25": {"scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 5, 10], "colmap": "coolwarm"},
-    "proxydryss": {"scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2], "colmap": "coolwarm"},
-    "dryss": {"scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2], "colmap": "coolwarm"},
-    "proxydryna": {
-        "scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 5, 10, 20, 50, 100, 200],
-        "colmap": "coolwarm",
-    },
-    "dryna": {
-        "scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 5, 10, 20, 50, 100, 200],
-        "colmap": "coolwarm",
-    },
-    "proxydryno2": {
-        "scale": [0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0, 2],
-        "colmap": "coolwarm",
-    },
-    "dryno2": {
-        "scale": [0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0, 2],
-        "colmap": "coolwarm",
-    },
-    "proxydryhono": {
-        "scale": [0.0, 0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.008, 0.01, 0.02],
-        "colmap": "coolwarm",
-    },
-    "dryhono": {
-        "scale": [0.0, 0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.008, 0.01, 0.02],
-        "colmap": "coolwarm",
-    },
-    "proxydryn2o5": {
-        "scale": [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.2],
-        "colmap": "coolwarm",
-    },
-    "dryn2o5": {
-        "scale": [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.2],
-        "colmap": "coolwarm",
-    },
-    "proxydryhno3": {
-        "scale": [0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0, 2.0, 5.0],
-        "colmap": "coolwarm",
-    },
-    "dryhno3": {
-        "scale": [0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0, 2.0, 5.0],
-        "colmap": "coolwarm",
-    },
-    "proxydryno3c": {
-        "scale": [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.5],
-        "colmap": "coolwarm",
-    },
-    "dryno3c": {
-        "scale": [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.5],
-        "colmap": "coolwarm",
-    },
-    "proxydryno3f": {
-        "scale": [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.5],
-        "colmap": "coolwarm",
-    },
-    "dryno3f": {"scale": [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.5], "colmap": "coolwarm"},
-    "proxydrynh3": {
-        "scale": [0, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 1, 2, 5],
-        "colmap": "coolwarm",
-    },
-    "drynh3": {
-        "scale": [0, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 1, 2, 5],
-        "colmap": "coolwarm",
-    },
-    "proxydrynh4": {
-        "scale": [0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0],
-        "colmap": "coolwarm",
-    },
-    "drynh4": {
-        "scale": [0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0],
-        "colmap": "coolwarm",
-    },
-    "proxydryso2": {
-        "scale": [0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0, 2, 5],
-        "colmap": "coolwarm",
-    },
-    "dryso2": {
-        "scale": [0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.5, 1.0, 2, 5],
-        "colmap": "coolwarm",
-    },
-    "proxydryso4": {
-        "scale": [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.2, 0.5],
-        "colmap": "coolwarm",
-    },
-    "dryso4": {
-        "scale": [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.2, 0.5],
-        "colmap": "coolwarm",
-    },
-    "proxydryoxs": {
-        "scale": [0, 0.05, 0.1, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40],
-        "colmap": "coolwarm",
-    },
-    "proxydryoxn": {
-        "scale": [0, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80],
-        "colmap": "coolwarm",
-    },
-    "proxydryrdn": {
-        "scale": [0, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80],
-        "colmap": "coolwarm",
-    },
-    "depoxs": {
-        "scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 5, 10, 20],
-        "colmap": "coolwarm",
-    },
-    "depna": {
-        "scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 5, 10, 20, 50, 100, 200],
-        "colmap": "coolwarm",
-    },
-    "depoxn": {
-        "scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 5, 10, 20],
-        "colmap": "coolwarm",
-    },
-    "deprdn": {
-        "scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 5, 10, 20, 50, 100, 200],
-        "colmap": "coolwarm",
-    },
-    "depoxsf": {
-        "scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 5, 10, 20],
-        "colmap": "coolwarm",
-    },
-    "depnaf": {
-        "scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 5, 10, 20],
-        "colmap": "coolwarm",
-    },
-    "depoxnf": {
-        "scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 5, 10, 20],
-        "colmap": "coolwarm",
-    },
-    "deprdnf": {
-        "scale": [0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 5, 10, 20, 50, 100, 200],
-        "colmap": "coolwarm",
-    },
-    "bsc532aer": {
-        "scale": [0.0, 0.0005, 0.001, 0.0015, 0.002, 0.0025, 0.003, 0.0035, 0.004],
-        "colmap": "coolwarm",
-    },
-    "ec532aer": {
-        "scale": [0, 0.004, 0.008, 0.012, 0.016, 0.02, 0.04, 0.06, 0.08, 0.1, 0.2, 0.3, 0.4],
-        "colmap": "coolwarm",
-    },
-}
+import copy
+import json
+import logging
+from configparser import ConfigParser
+from enum import Enum
+from typing import NamedTuple
+
+from pydantic import BaseModel
+
+from pyaerocom.data import resources
+
+logger = logging.getLogger(__name__)
+
+
+# basemodel-implementation for verification
+class _ScaleAndColmap(NamedTuple):
+    scale: list[float]
+    colmap: str
+
+
+class _VarWebScaleAndColormap(BaseModel):
+    scale_colmaps: dict[str, _ScaleAndColmap]
+
+
+# dict-implementation for json-serialization, namedtuple not stable with json/simplejson
+class ScaleAndColmap(dict[str, str | list[float]]):
+    """simple dictionary container with only two keys, scale and colmap"""
+
+    pass
+
+
+class VarWebScaleAndColormap(dict[str, ScaleAndColmap]):
+    def __init__(self, *args, **kwargs):
+        # run arguments through pydantic
+        wvsc = _VarWebScaleAndColormap(scale_colmaps=kwargs)
+        super().__init__(**{x: y._asdict() for x, y in wvsc.scale_colmaps.items()})
+
+    def __init__(self, config_file="", **kwargs):
+        """This class contains scale and colmap informations and is implemented as dict to allow
+        json serialization. It reads it inital data from data/var_scale_colmap.ini.
+
+        :param config_file: filename to additional or updated information, defaults to None
+        """
+        super().__init__()
+        with resources.path("pyaerocom.aeroval.data", "var_scale_colmap.ini") as file:
+            self.update_from_ini(file)
+        if config_file != "":
+            logger.info(f"Reading additional web-scales from '{config_file}'")
+            self.update_from_ini(config_file)
+        self.update(**kwargs)
+
+    def update(self, **kwargs):
+        wvsc = _VarWebScaleAndColormap(scale_colmaps=kwargs)
+        super().update(**{x: y._asdict() for x, y in wvsc.scale_colmaps.items()})
+
+    def update_from_ini(self, filename):
+        cfg = ConfigParser()
+        cfg.read(filename)
+        # remove configparser default
+        cfg_dict = dict()
+        keys = ("scale", "colmap")
+        for s in cfg.sections():
+            items = []
+            for k in keys:
+                if k in cfg[s]:
+                    if k == "scale":
+                        try:
+                            items.append(json.loads(cfg[s][k]))
+                        except Exception as ex:
+                            raise KeyError(
+                                f"wrong value for '{k}' of var '{s}' in {filename}: {ex}"
+                            )
+                    else:
+                        items.append(cfg[s][k])
+                else:
+                    raise KeyError(f"missing '{k}' for var '{s}' in {filename}")
+            cfg_dict[s] = tuple(items)
+        self.update(**cfg_dict)
+
+    def write(self, filename: str):
+        """write the scales and colormaps to a configuration file
+
+        :param filename: path to a filename, currently a .ini file
+        """
+        cfg = ConfigParser()
+        cfg.update(self)
+        with open(filename, "w") as fh:
+            cfg.write(fh)
+
+
+#: Mapping of pyaerocom variable names to web naming conventions
+class VerticalType(str, Enum):
+    """A 2D variable is defined under Column on the website, 3D is defined under Surface"""
+
+    T2D = "2D"
+    T3D = "3D"
+    UNDEFINED = "UNDEFINED"
+
+    def __str__(self):
+        return self.value
+
+
+class CategoryType(str, Enum):
+    optical = "Optical properties"
+    particle_conc = "Particle concentrations"
+    height = "Height"
+    concentration = "Concentration"
+    gas_conc = "Gas concentrations"
+    vmr = "Volume mixing ratios"
+    gas_vmr = "Gas volume mixing ratio"
+    deposition = "Deposition"
+    temperature = "Temperature"
+    particle_ratio = "Particle ratio"
+    UNDEFINED = "UNDEFINED"
+
+    def __str__(self):
+        return self.value
+
+
+class VariableInfo(NamedTuple):
+    menu_name: str
+    vertical_type: VerticalType
+    category: CategoryType
+
+
+class _VarWebInfo(BaseModel):
+    """Pydantic helper class to ensure the VarWebInfo container always contains the correct data
+
+    :param BaseModel: _description_
+    """
+
+    var_web_info: dict[str, VariableInfo]
+
+
+class VarWebInfo:
+    _var_web_info: _VarWebInfo
+
+    def __init__(self, config_file="", **kwargs):
+        """This class contains var_web_info and can be accessed like a read-only dict. It
+        reads it inital data from data/var_web_info.ini
+
+        :param config_file: filename to additional or updated VariableInfo items, defaults to None
+        """
+        self._var_web_info = _VarWebInfo(var_web_info=dict())
+        with resources.path("pyaerocom.aeroval.data", "var_web_info.ini") as file:
+            self.update_from_ini(file)
+        if config_file != "":
+            self.update_from_ini(config_file)
+        self.update(**kwargs)
+
+    def update(self, *args, **kwargs):
+        d = copy.deepcopy(self._var_web_info.var_web_info)
+        d.update(*args, **kwargs)
+        self._var_web_info = _VarWebInfo(var_web_info=d)
+
+    def update_from_ini(self, filename):
+        cfg = ConfigParser()
+        cfg.read(filename)
+        # remove configparser default
+        cfg_dict = dict()
+        keys = ("menu_name", "vertical_type", "category")
+        for s in cfg.sections():
+            items = []
+            for k in keys:
+                if k in cfg[s]:
+                    items.append(cfg[s][k])
+                else:
+                    raise KeyError(f"missing '{k}' for var '{s}' in {filename}")
+            cfg_dict[s] = tuple(items)
+        self.update(**cfg_dict)
+
+    ## below functions to behave like a read-only dict
+    def copy(self):
+        return self._var_web_info.var_web_info.copy()
+
+    def __getitem__(self, key):
+        return self._var_web_info.var_web_info[key]
+
+    def __len__(self, key):
+        return self._var_web_info.var_web_info.__len__()
+
+    def __repr__(self):
+        return repr(self._var_web_info.var_web_info)
+
+    def keys(self):
+        return self._var_web_info.var_web_info.keys()
+
+    def has_key(self, k):
+        return k in self._var_web_info.var_web_info
+
+    def values(self):
+        return self._var_web_info.var_web_info.values()
+
+    def items(self):
+        return self._var_web_info.var_web_info.items()
+
+    def __cmp__(self, dict_):
+        return self._var_web_info.var_web_info.__cmp__(dict_)
+
+    def __contains__(self, item):
+        return self._var_web_info.var_web_info.__contains__(item)
+
+    def __iter__(self):
+        return self._var_web_info.var_web_info.__iter__()
+
+    def __unicode__(self):
+        return self._var_web_info.var_web_info.__unicode__()
+
 
 #: Default information for statistical parameters
 statistics_defaults = {
@@ -568,173 +413,3 @@
         "decimals": 2,
     },
 }
-
-#: Mapping of pyaerocom variable names to web naming conventions
-## Note: A 2D variable is defined under Column on the website, 3D is defined under Surface
-
-var_web_info = dict(
-    od550aer=["AOD", "2D", "Optical properties"],
-    od550csaer=["AOD (clear sky)", "2D", "Optical properties"],
-    od550lt1aer=["AODf", "2D", "Optical properties"],
-    od550gt1aer=["AODc", "2D", "Optical properties"],
-    od550dust=["AODdust", "2D", "Optical properties"],
-    abs550aer=["AAOD", "2D", "Optical properties"],
-    ssa670aer=["SSA", "2D", "Optical properties"],
-    ang4487aer=["AE", "2D", "Optical properties"],
-    angabs4487aer=["AAE", "2D", "Optical properties"],
-    ang4487csaer=["AE (clear sky)", "2D", "Optical properties"],
-    sc550dryaer=["Scat. coef. (dry)", "3D", "Optical properties"],
-    sc550aer=["Scat. coef.", "3D", "Optical properties"],
-    ac550aer=["Abs. coef.", "3D", "Optical properties"],
-    ac550dryaer=["Abs. coef. (dry)", "3D", "Optical properties"],
-    ec532aer=["Ext. coeff.", "3D", "Optical properties"],
-    bsc532aer=["Backscat. coeff.", "3D", "Optical properties"],
-    concso4pr=["SO4 (precip.)", "3D", "Particle concentrations"],
-    concbc=["BC", "3D", "Particle concentrations"],
-    concoa=["OA", "3D", "Particle concentrations"],
-    concss=["SS", "3D", "Particle concentrations"],
-    conco3=["O3", "3D", "Gas concentrations"],
-    concno310=["NO3_PM10", "3D", "Particle concentration"],
-    concno325=["NO3_PM25", "3D", "Particle concentration"],
-    proxyod550bc=["OD (Black Carbon)", "2D", "Optical properties"],
-    proxyod550dust=["OD (Dust)", "2D", "Optical properties"],
-    proxyod550oa=["OD (Organic Matter)", "2D", "Optical properties"],
-    proxyod550so4=["OD (SO4)", "2D", "Optical properties"],
-    proxyod550ss=["OD (Sea Salt)", "2D", "Optical properties"],
-    proxyod550nh4=["OD (NH4)", "2D", "Optical properties"],
-    proxyod550no3=["OD (NO3)", "2D", "Optical properties"],
-    proxyzdust=["DLH", "2D", "Height"],
-    zdust=["DLH", "2D", "Height"],
-    proxyzaerosol=["ALH", "2D", "Height"],
-    zaerosol=["ALH", "2D", "Height"],
-    # Gases
-    concNno=["NO", "3D", "Concentration"],
-    concno2=["NO2", "3D", "Gas concentrations"],
-    concNno2=["NO2", "3D", "Gas concentrations"],
-    vmrno=["NO", "3D", "Volume mixing ratios"],
-    vmrno2=["NO2", "3D", "Volume mixing ratios"],
-    concno3=["NO3", "3D", "Gas concentrations"],
-    conctno3=["tNO3", "3D", "Concentration"],
-    concNtno3=["tNO3", "3D", "Concentration"],
-    conchno3=["HNO3", "3D", "Concentration"],
-    concNhno3=["HNO3", "3D", "Concentration"],
-    concnh3=["NH3", "3D", "Concentration"],
-    concNnh3=["NH3", "3D", "Concentration"],
-    conctnh=["tNH", "3D", "Concentration"],
-    concNtnh=["tNH", "3D", "Concentration"],
-    concnh4=["NH4", "3D", "Gas concentrations"],
-    concNnh4=["NH4", "3D", "Gas concentrations"],
-    concso2=["SO2", "3D", "Gas concentrations"],
-    concSso2=["SO2", "3D", "Gas concentrations"],
-    vmrso2=["SO2", "3D", "Gas volume mixing ratio"],
-    concso4=["SO4", "3D", "Particle concentrations"],
-    vmro3=["O3", "3D", "Volume mixing ratios"],
-    vmro3mda8=["O3 (MDA8)", "3D", "Valume mixing ratios"],
-    vmro3max=["O3Max", "3D", "Volume mixing ratios"],
-    vmrox=["OX", "3D", "Gas volume mixing ratio"],
-    concco=["CO", "3D", "Particle concentration"],
-    vmrco=["CO", "3D", "Volume mixing ratios"],
-    vmrco2=["CO2", "3D", "Volume mixing ratios"],
-    vmrc2h2=["Ethyne", "3D", "Volume mixing ratios"],
-    vmrc2h4=["Ethylene", "3D", "Volume mixing ratios"],
-    vmrc2h6=["Ethane", "3D", "Volume mixing ratios"],
-    vmrhcho=["Formaldehyde", "3D", "Volume mixing ratios"],
-    vmrisop=["Isoprene", "3D", "Volume mixing ratios"],
-    vmrch4=["CH4", "3D", "Volume mixing ratios"],
-    # PMs
-    concpm10=["PM10", "3D", "Particle concentrations"],
-    concpm10pbap=["PM10 PBAP", "3D", "Particle concentrations incl. spores"],
-    concpm25=["PM2.5", "3D", "Particle concentrations"],
-    concNno3pm10=["NO3 PM10", "3D", "Particle concentration"],
-    concNno3pm25=["NO3 PM25", "3D", "Particle concentration"],
-    concno3pm10=["NO3 PM10", "3D", "Particle concentration"],
-    concno3pm25=["NO3 PM25", "3D", "Particle concentration"],
-    concnh4coarse=["NH4 PM10", "3D", "Particle concentrations"],
-    concnh4fine=["NH4 PM2.5", "3D", "Particle concentrations"],
-    concso4t=["SO4 total", "3D", "Particle concentration"],
-    concso4c=["SO4 sea salt corrected", "3D", "Particle concentration"],
-    concso4coarse=["SO4 PM10", "3D", "Particle concentration"],
-    concso4fine=["SO4 PM2.5", "3D", "Particle concentration"],
-    concss10=["SS PM10", "3D", "Particle concentration"],
-    concss25=["SS PM25", "3D", "Particle concentration"],
-    concec=["EC", "3D", "Particle concentration"],
-    conccoc=["OC", "3D", "Particle concentration"],
-    concsspm10=["SS PM10", "3D", "Particle concentration"],
-    concsspm25=["SS PM25", "3D", "Particle concentration"],
-    concCecpm25=["EC PM2.5", "3D", "Particle concentration"],
-    concCocpm25=["OC PM2.5", "3D", "Particle concentration"],
-    concCec25=["EC PM2.5", "3D", "Particle concentration"],
-    concCoc25=["OC PM2.5", "3D", "Particle concentration"],
-    concom25=["OM PM2.5", "3D", "Particle concentration"],
-    concCecpm10=["EC PM10", "3D", "Particle concentration"],
-    concCocpm10=["OC PM10", "3D", "Particle concentration"],
-    concdust=["Dust concentration", "3D", "Particle concentration"],
-    # Depositions
-    depoxs=["TotDepOXS", "3D", "Deposition"],
-    deprdn=["TotDepRDN", "3D", "Deposition"],
-    depoxn=["TotDepOXN", "3D", "Deposition"],
-    depoxsf=["TotDepOXSforr", "3D", "Deposition"],
-    deprdnf=["TotDepRDNforr", "3D", "Deposition"],
-    depoxnf=["TotDepOXNforr", "3D", "Deposition"],
-    depss=["TotDepSS", "3D", "Deposition"],
-    depssf=["TotDepSSforr", "3D", "Deposition"],
-    depna=["TotDepNa", "3D", "Deposition"],
-    depnaf=["TotDepNaforr", "3D", "Deposition"],
-    drysox=["DryOXS", "3D", "Deposition"],
-    dryoxs=["DryOXS", "3D", "Deposition"],
-    dryoxn=["DryOXN", "3D", "Deposition"],
-    dryrdn=["DryRDN", "3D", "Deposition"],
-    depdust=["TotDustDep", "3D", "Deposition"],
-    drydust=["DryDustDep", "3D", "Deposition"],
-    wetdust=["WetDustDep", "3D", "Deposition"],
-    wetoxs=["WetOXS", "3D", "Deposition"],
-    wetna=["WetNa", "3D", "Deposition"],
-    wetoxsc=["WetOXScorr", "3D", "Deposition"],
-    wetoxst=["WetOXStot", "3D", "Deposition"],
-    wetoxn=["WetOXN", "3D", "Deposition"],
-    wetrdn=["WetRDN", "3D", "Deposition"],
-    prmm=["Precipitation", "3D", "Deposition"],
-    # Temperature
-    ts=["Surface Temperature", "3D", "Temperature"],
-    # proxy drydep
-    proxydryoxs=["proxyDryOXS", "3D", "Deposition"],
-    proxydryss=["proxyDrySS", "3D", "Deposition"],
-    proxydryna=["proxyDryNa", "3D", "Deposition"],
-    proxydryso2=["proxyDrySO2", "3D", "Deposition"],
-    proxydryso4=["proxyDrySO4", "3D", "Deposition"],
-    proxydryoxn=["proxyDryOXN", "3D", "Deposition"],
-    proxydryno2=["proxyDryNO2", "3D", "Deposition"],
-    proxydryno2no2=["proxyDryNO2NO2", "3D", "Deposition"],
-    proxydryhono=["proxyDryHONO", "3D", "Deposition"],
-    proxydryn2o5=["proxyDryN2O5", "3D", "Deposition"],
-    proxydryhno3=["proxyDryHNO3", "3D", "Deposition"],
-    proxydryno3c=["proxyDryNO3Coarse", "3D", "Deposition"],
-    proxydryno3f=["proxyDryNO3Fine", "3D", "Deposition"],
-    proxydryrdn=["proxyDryRDN", "3D", "Deposition"],
-    proxydrynh3=["proxyDryNH3", "3D", "Deposition"],
-    proxydrynh4=["proxyDryNH4", "3D", "Deposition"],
-    proxydryo3=["proxyDryO3", "3D", "Deposition"],
-    proxydrypm10=["proxyDryPM10", "3D", "Deposition"],
-    proxydrypm25=["proxyDryPM2.5", "3D", "Deposition"],
-    # proxy wetdep
-    proxywetoxs=["proxyWetOXS", "3D", "Deposition"],
-    proxywetso2=["proxyWetSO2", "3D", "Deposition"],
-    proxywetso4=["proxyWetSO4", "3D", "Deposition"],
-    proxywetoxn=["proxyWetOXN", "3D", "Deposition"],
-    proxywetno2=["proxyWetNO2", "3D", "Deposition"],
-    proxywetno2no2=["proxyWetNO2NO2", "3D", "Deposition"],
-    proxywethono=["proxyWetHONO", "3D", "Deposition"],
-    proxywetn2o5=["proxyWetN2O5", "3D", "Deposition"],
-    proxywethno3=["proxyWetHNO3", "3D", "Deposition"],
-    proxywetno3c=["proxyWetNO3Coarse", "3D", "Deposition"],
-    proxywetno3f=["proxyWetNO3Fine", "3D", "Deposition"],
-    proxywetrdn=["proxyWetRDN", "3D", "Deposition"],
-    proxywetnh3=["proxyWetNH3", "3D", "Deposition"],
-    proxywetnh4=["proxyWetNH4", "3D", "Deposition"],
-    proxyweto3=["proxyWetO3", "3D", "Deposition"],
-    proxywetpm10=["proxyWetPM10", "3D", "Deposition"],
-    proxywetpm25=["proxyWetPM2.5", "3D", "Deposition"],
-    # other stuff
-    ratpm25pm10=["ratio PM2.5 PM10", "3D", "Particle ratio"],
-    ratpm10pm25=["ratio PM10 PM2.5", "3D", "Particle ratio"],
-)
diff --git a/pyaerocom/aeroval/helpers.py b/pyaerocom/aeroval/helpers.py
index 903968bbd..cdcd2f903 100644
--- a/pyaerocom/aeroval/helpers.py
+++ b/pyaerocom/aeroval/helpers.py
@@ -18,42 +18,6 @@
 logger = logging.getLogger(__name__)
 
 
-def check_var_ranges_avail(model_data, var_name):
-    """
-    Check if lower and upper variable ranges are available for input variable
-
-    Parameters
-    ----------
-    model_data : GriddedData
-        modeldata containing variable data
-    var_name : str
-        variable name to be checked (must be the same as model data
-        AeroCom variable name).
-
-    Raises
-    ------
-    ValueError
-        if ranges for input variable are not defined and if input model data
-        corresponds to a different variable than the input variable name.
-
-    Returns
-    -------
-    None
-
-    """
-    try:
-        VarinfoWeb(var_name)
-    except AttributeError as aex:
-        if model_data.var_name_aerocom == var_name:
-            logger.info(f"re-registering var {var_name} due to: {aex}")
-            model_data.register_var_glob(delete_existing=True)
-        else:
-            raise ValueError(
-                f"Mismatch between variable name of input model_data "
-                f"({model_data.var_name_aerocom}) and var_name {var_name}"
-            )
-
-
 def _check_statistics_periods(periods: list) -> list:
     """
     Check input list of period strings is valid
diff --git a/pyaerocom/aeroval/modelmaps_engine.py b/pyaerocom/aeroval/modelmaps_engine.py
index 86b561bdf..7d04722e3 100644
--- a/pyaerocom/aeroval/modelmaps_engine.py
+++ b/pyaerocom/aeroval/modelmaps_engine.py
@@ -3,8 +3,6 @@
 
 from pyaerocom import GriddedData, TsType
 from pyaerocom.aeroval._processing_base import DataImporter, ProcessingEngine
-from pyaerocom.aeroval.glob_defaults import var_ranges_defaults
-from pyaerocom.aeroval.helpers import check_var_ranges_avail
 from pyaerocom.aeroval.json_utils import write_json
 from pyaerocom.aeroval.modelmaps_helpers import calc_contour_json, griddeddata_to_jsondict
 from pyaerocom.aeroval.varinfo_web import VarinfoWeb
@@ -142,8 +140,7 @@ def _process_map_var(self, model_name, var, reanalyse_existing):
                 f"Cannot read data for model {model_name} (variable {var}): {e}"
             )
 
-        check_var_ranges_avail(data, var)
-
+        var_ranges_defaults = self.cfg.var_scale_colmap
         if var in var_ranges_defaults.keys():
             cmapinfo = var_ranges_defaults[var]
             varinfo = VarinfoWeb(var, cmap=cmapinfo["colmap"], cmap_bins=cmapinfo["scale"])
diff --git a/pyaerocom/aeroval/setupclasses.py b/pyaerocom/aeroval/setupclasses.py
index fd99d8c6b..97ce41383 100644
--- a/pyaerocom/aeroval/setupclasses.py
+++ b/pyaerocom/aeroval/setupclasses.py
@@ -7,6 +7,8 @@
 from pathlib import Path
 from typing import Annotated, Literal
 
+from pyaerocom.aeroval.glob_defaults import VarWebInfo, VarWebScaleAndColormap
+
 if sys.version_info >= (3, 11):
     from typing import Self
 else:
@@ -57,7 +59,7 @@ class OutputPaths(BaseModel):
     # Pydantic ConfigDict
     model_config = ConfigDict(arbitrary_types_allowed=True)
 
-    JSON_SUBDIRS: list[str] = [
+    _JSON_SUBDIRS: list[str] = [
         "map",
         "ts",
         "ts/diurnal",
@@ -83,8 +85,6 @@ def validate_basedirs(cls, v):
             tmp.mkdir(parents=True, exist_ok=True)
         return v
 
-    ADD_GLOB: list[str] = ["coldata_basedir", "json_basedir"]
-
     proj_id: str
     exp_id: str
 
@@ -100,7 +100,7 @@ def get_coldata_dir(self, assert_exists=True):
     def get_json_output_dirs(self, assert_exists=True):
         out = {}
         base = os.path.join(self.json_basedir, self.proj_id, self.exp_id)
-        for subdir in self.JSON_SUBDIRS:
+        for subdir in self._JSON_SUBDIRS:
             loc = self._check_init_dir(os.path.join(base, subdir), assert_exists)
             out[subdir] = loc
         # for cams2_83 the extra 'forecast' folder will contain the median scores if computed
@@ -300,16 +300,17 @@ class EvalSetup(BaseModel):
     ## Regular & BaseModel-based Attributes
     ########################################
 
-    IGNORE_JSON: list[str] = ["_aux_funs"]
-    ADD_GLOB: list[str] = ["io_aux_file"]
-
     io_aux_file: Annotated[
         Path | str, ".py file containing additional read methods for modeldata"
     ] = ""
 
-    _aux_funs: dict = {}
+    var_web_info_file: Annotated[Path | str, "config file containing additional variables"] = ""
 
-    var_web_info: dict = {}
+    var_scale_colmap_file: Annotated[
+        Path | str, "config file containing scales/ranges for variables"
+    ] = ""
+
+    _aux_funs: dict = {}
 
     @computed_field
     @cached_property
@@ -343,6 +344,14 @@ def gridded_aux_funs(self) -> dict:
             self._import_aux_funs()
         return self._aux_funs
 
+    @cached_property
+    def var_web_info(self) -> VarWebInfo:
+        return VarWebInfo(config_file=self.var_web_info_file)
+
+    @cached_property
+    def var_scale_colmap(self) -> VarWebScaleAndColormap:
+        return VarWebScaleAndColormap(config_file=self.var_scale_colmap_file)
+
     @computed_field
     @cached_property
     def path_manager(self) -> OutputPaths:
diff --git a/pyaerocom/data/resources.py b/pyaerocom/data/resources.py
index 9feda2c52..868e98197 100644
--- a/pyaerocom/data/resources.py
+++ b/pyaerocom/data/resources.py
@@ -15,6 +15,7 @@
 def path(package: str, resource: str) -> ContextManager[Path]:
     """A context manager providing a file path object to the resource.
     If the resource does not already exist on its own on the file system,
+    e.g. it only exists in a zip-file, the resource will be extracted and
     a temporary file will be created. If the file was created, the file
     will be deleted upon exiting the context manager (no exception is
     raised if the file was deleted prior to the context manager


Test patch:
diff --git a/tests/aeroval/data/buggy_var_scale_colmap.ini b/tests/aeroval/data/buggy_var_scale_colmap.ini
new file mode 100644
index 000000000..913946e56
--- /dev/null
+++ b/tests/aeroval/data/buggy_var_scale_colmap.ini
@@ -0,0 +1,8 @@
+# This file is intentionally buggy
+[deprdn]
+scale = 1, 2
+colmap = lukewarm
+
+[newvar]
+scale = [5, 6]
+colmap = coolwarm
diff --git a/tests/aeroval/data/buggy_var_web_info.ini b/tests/aeroval/data/buggy_var_web_info.ini
new file mode 100644
index 000000000..8a9a04bed
--- /dev/null
+++ b/tests/aeroval/data/buggy_var_web_info.ini
@@ -0,0 +1,9 @@
+# This file is intentionally buggy
+[deprdn]
+menu_name = MyDepRdn
+vertical_type = 3D
+category = NoCat
+
+[newvar]
+menu_name = NewVar
+vertical_type = NoVType
diff --git a/tests/aeroval/data/user_var_scale_colmap.ini b/tests/aeroval/data/user_var_scale_colmap.ini
new file mode 100644
index 000000000..f0a062c2a
--- /dev/null
+++ b/tests/aeroval/data/user_var_scale_colmap.ini
@@ -0,0 +1,7 @@
+[deprdn]
+scale = [1, 2]
+colmap = lukewarm
+
+[newvar]
+scale = [5, 6]
+colmap = coolwarm
diff --git a/tests/aeroval/data/user_var_web_info.ini b/tests/aeroval/data/user_var_web_info.ini
new file mode 100644
index 000000000..ae8a2b92b
--- /dev/null
+++ b/tests/aeroval/data/user_var_web_info.ini
@@ -0,0 +1,9 @@
+[deprdn]
+menu_name = MyDepRdn
+vertical_type = 3D
+category = Deposition
+
+[newvar]
+menu_name = NewVar
+vertical_type = 3D
+category = Deposition
diff --git a/tests/aeroval/test_glob_defaults.py b/tests/aeroval/test_glob_defaults.py
index ef3be254e..934e43962 100644
--- a/tests/aeroval/test_glob_defaults.py
+++ b/tests/aeroval/test_glob_defaults.py
@@ -1,6 +1,7 @@
-from pyaerocom.aeroval.glob_defaults import var_web_info
+from pyaerocom.aeroval.glob_defaults import VarWebInfo
 
 
 def test_var_web_info():
+    var_web_info = VarWebInfo()
     unique_entries = list(set(var_web_info))
     assert len(unique_entries) == len(var_web_info.keys())
diff --git a/tests/aeroval/test_helpers.py b/tests/aeroval/test_helpers.py
index 66f03e654..55dbe4d14 100644
--- a/tests/aeroval/test_helpers.py
+++ b/tests/aeroval/test_helpers.py
@@ -8,33 +8,9 @@
     _get_min_max_year_periods,
     _period_str_to_timeslice,
     check_if_year,
-    check_var_ranges_avail,
     make_dummy_model,
 )
 from pyaerocom.aeroval.setupclasses import EvalSetup
-from pyaerocom.exceptions import VariableDefinitionError
-from pyaerocom.griddeddata import GriddedData
-
-
-@pytest.mark.parametrize(
-    "dvar,var",
-    [
-        ("od550aer", "od550aer"),
-        ("od550aer", "od550gt1aer"),
-        ("pr", "prmm"),
-        ("prmm", "prmm"),
-    ],
-)
-def test_check_var_ranges_avail(data_tm5: GriddedData, dvar: str, var: str):
-    data = data_tm5.copy()
-    data.var_name = dvar
-    check_var_ranges_avail(data, var)
-
-
-def test_check_var_ranges_avail_error(data_tm5: GriddedData):
-    with pytest.raises(VariableDefinitionError) as e:
-        check_var_ranges_avail(data_tm5, "bla")
-    assert str(e.value) == "Error (VarCollection): input variable bla is not supported"
 
 
 @pytest.mark.parametrize(
diff --git a/tests/aeroval/test_setupclasses.py b/tests/aeroval/test_setupclasses.py
index 724d6ef33..e3a6451fb 100644
--- a/tests/aeroval/test_setupclasses.py
+++ b/tests/aeroval/test_setupclasses.py
@@ -1,4 +1,6 @@
+import os
 from copy import deepcopy
+from typing import Literal
 
 import pytest
 
@@ -127,7 +129,11 @@ def test_EvalSetup_TimeSetup(eval_setup: EvalSetup, cfg_exp1: dict):
         ),
     ),
 )
-def test_EvalSetup__check_time_config(eval_setup: EvalSetup, start, stop):
+def test_EvalSetup__check_time_config(
+    eval_setup: EvalSetup,
+    start: Literal["2022", "2022/01/12 00:00:00"],
+    stop: Literal["2023", "2022/01/12 23:00:00"],
+):
     eval_setup._check_time_config()
     assert str(eval_setup.colocation_opts.start) == start
     assert str(eval_setup.colocation_opts.stop) == stop
@@ -261,3 +267,55 @@ def test_EvalSetup_WebDisplaySetup(eval_setup: EvalSetup, cfg_exp1: dict):
     assert webdisp_opts.modelorder_from_config is True
     assert "obsorder_from_config" not in cfg_exp1
     assert webdisp_opts.obsorder_from_config is True
+
+
+@default_config
+def test_user_var_scale_colmap(cfg_exp1: dict):
+    es1 = EvalSetup(**cfg_exp1)
+    assert "deprdn" in es1.var_scale_colmap
+
+    cfg = cfg_exp1.copy()
+    cfg["var_scale_colmap_file"] = os.path.join(
+        os.path.dirname(__file__), "data", "user_var_scale_colmap.ini"
+    )
+    esX = EvalSetup(**cfg)
+    assert "deprdn" in esX.var_scale_colmap
+    assert "newvar" in esX.var_scale_colmap
+    assert esX.var_scale_colmap["deprdn"]["colmap"] != es1.var_scale_colmap["deprdn"]["colmap"]
+    assert esX.var_scale_colmap["deprdn"]["scale"] != es1.var_scale_colmap["deprdn"]["scale"]
+
+    cfg_fail = cfg_exp1.copy()
+    cfg_fail["var_scale_colmap_file"] = os.path.join(
+        os.path.dirname(__file__), "data", "buggy_var_scale_colmap.ini"
+    )
+    esY = EvalSetup(**cfg_fail)
+    with pytest.raises(KeyError) as e:
+        _ = esY.var_scale_colmap
+    assert "buggy_var_scale_colmap.ini" in str(e.value)
+    assert "scale" in str(e.value)
+
+
+@default_config
+def test_user_var_web_info(cfg_exp1: dict):
+    es1 = EvalSetup(**cfg_exp1)
+    assert "deprdn" in es1.var_web_info
+
+    cfg = cfg_exp1.copy()
+    cfg["var_web_info_file"] = os.path.join(
+        os.path.dirname(__file__), "data", "user_var_web_info.ini"
+    )
+    esX = EvalSetup(**cfg)
+    assert "deprdn" in esX.var_web_info
+    assert "newvar" in esX.var_web_info
+    assert esX.var_web_info["deprdn"][0] != es1.var_web_info["deprdn"][0]
+
+    cfg_fail = cfg_exp1.copy()
+    cfg_fail["var_web_info_file"] = os.path.join(
+        os.path.dirname(__file__), "data", "buggy_var_web_info.ini"
+    )
+    esY = EvalSetup(**cfg_fail)
+    with pytest.raises(KeyError) as e:
+        _ = esY.var_web_info
+
+    assert "buggy_var_web_info.ini" in str(e.value)
+    assert "category" in str(e.value)