diff --git a/climada/engine/unsequa/input_var.py b/climada/engine/unsequa/input_var.py index 56a47fe845..76e63d766e 100644 --- a/climada/engine/unsequa/input_var.py +++ b/climada/engine/unsequa/input_var.py @@ -246,9 +246,8 @@ def haz(haz_list, n_ev=None, bounds_int=None, bounds_frac=None, bounds_freq=None The frequency of all events is multiplied by a number sampled uniformly from a distribution with (min, max) = bounds_freq HL: sample uniformly from hazard list - From the provided list of hazard is elements are uniformly - sampled. For example, Hazards outputs from dynamical models - for different input factors. + For each sample, one element is drawn uniformly from the provided list of hazards. + For example, Hazards outputs from dynamical models for different input factors. If a bounds is None, this parameter is assumed to have no uncertainty. @@ -310,8 +309,8 @@ def exp(exp_list, bounds_totval=None, bounds_noise=None): with (min, max) = bounds_noise. EN is the value of the seed for the uniform random number generator. EL: sample uniformly from exposure list - From the provided list of exposure is elements are uniformly - sampled. For example, LitPop instances with different exponents. + For each sample, one element is drawn uniformly from the provided list of exposures. + For example, LitPop instances with different exponents. If a bounds is None, this parameter is assumed to have no uncertainty. @@ -376,9 +375,8 @@ def impfset( sampled uniformly from a distribution with (min, max) = bounds_int IL: sample uniformly from impact function set list - From the provided list of impact function sets elements are uniformly - sampled. For example, impact functions obtained from different - calibration methods. + For each sample, one element is drawn uniformly from the provided list of impact function sets. + For example, impact functions obtained from different calibration methods. If a bounds is None, this parameter is assumed to have no uncertainty. @@ -468,8 +466,8 @@ def ent( with (min, max) = bounds_noise. EN is the value of the seed for the uniform random number generator. EL: sample uniformly from exposure list - From the provided list of exposure is elements are uniformly - sampled. For example, LitPop instances with different exponents. + For each sample, one element is drawn uniformly from the provided list of exposures. + For example, LitPop instances with different exponents. MDD: scale the mdd (homogeneously) The value of mdd at each intensity is multiplied by a number sampled uniformly from a distribution with @@ -483,9 +481,8 @@ def ent( sampled uniformly from a distribution with (min, max) = bounds_int IL: sample uniformly from impact function set list - From the provided list of impact function sets elements are uniformly - sampled. For example, impact functions obtained from different - calibration methods. + For each sample, one element is drawn uniformly from the provided list of impact function sets. + For example, impact functions obtained from different calibration methods. If a bounds is None, this parameter is assumed to have no uncertainty. @@ -566,7 +563,7 @@ def ent( bounds_noise=bounds_noise, exp_list=exp_list, meas_set=meas_set, - **kwargs + **kwargs, ), _ent_unc_dict( bounds_totval=bounds_totval, @@ -616,8 +613,8 @@ def entfut( with (min, max) = bounds_noise. EN is the value of the seed for the uniform random number generator. EL: sample uniformly from exposure list - From the provided list of exposure is elements are uniformly - sampled. For example, LitPop instances with different exponents. + For each sample, one element is drawn uniformly from the provided list of exposures. + For example, LitPop instances with different exponents. MDD: scale the mdd (homogeneously) The value of mdd at each intensity is multiplied by a number sampled uniformly from a distribution with @@ -631,9 +628,8 @@ def entfut( sampled uniformly from a distribution with (min, max) = bounds_impfi IL: sample uniformly from impact function set list - From the provided list of impact function sets elements are uniformly - sampled. For example, impact functions obtained from different - calibration methods. + For each sample, one element is drawn uniformly from the provided list of impact function sets. + For example, impact functions obtained from different calibration methods. If a bounds is None, this parameter is assumed to have no uncertainty. @@ -706,7 +702,7 @@ def entfut( impf_set_list=impf_set_list, exp_list=exp_list, meas_set=meas_set, - **kwargs + **kwargs, ), _entfut_unc_dict( bounds_eg=bounds_eg, diff --git a/doc/user-guide/climada_engine_unsequa.ipynb b/doc/user-guide/climada_engine_unsequa.ipynb index d1f60722fe..8c13638c9c 100644 --- a/doc/user-guide/climada_engine_unsequa.ipynb +++ b/doc/user-guide/climada_engine_unsequa.ipynb @@ -12,7 +12,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "This is a tutorial for the unsequa module in CLIMADA. A detailled description can be found in [Kropf (2021)](https://eartharxiv.org/repository/view/3123/)." + "This is a tutorial for the unsequa module in CLIMADA. A detailled description can be found in [Kropf et al. (2022)](https://doi.org/10.5194/gmd-15-7177-2022)." ] }, { @@ -31,7 +31,7 @@ "\n", "In this module, it is possible to perform global uncertainty analysis, as well as a sensitivity analysis. The word global is meant as opposition to the 'one-factor-at-a-time' (OAT) strategy. The OAT strategy, which consists in analyzing the effect of varying one model input factor at a time while keeping all other fixed, is popular among modellers, but has major shortcomings [Saltelli (2010)](https://www.sciencedirect.com/science/article/abs/pii/S1364815210001180), [Saltelli(2019)](http://www.sciencedirect.com/science/article/pii/S1364815218302822) and should not be used.\n", "\n", - "A rough schemata of how to perform uncertainty and sensitivity analysis (taken from [Kropf(2021)](https://eartharxiv.org/repository/view/3123/))" + "A rough schemata of how to perform uncertainty and sensitivity analysis (taken from [Kropf et al. (2022)](https://doi.org/10.5194/gmd-15-7177-2022)." ] }, { @@ -50,7 +50,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "1. [Kropf, C.M. et al. Uncertainty and sensitivity analysis for global probabilistic weather and climate risk modelling: an implementation in the CLIMADA platform (2021)](https://eartharxiv.org/repository/view/3123/)\n", + "1. [Kropf, C.M. et al. Uncertainty and sensitivity analysis for probabilistic weather and climate-risk modelling: an implementation in CLIMADA v.3.1.0. Geoscientific Model Development, 15, 7177–7201 (2022)](https://doi.org/10.5194/gmd-15-7177-2022).\n", "2. [Pianosi, F. et al. Sensitivity analysis of environmental models: A systematic review with practical workflow. Environmental Modelling & Software 79, 214–232 (2016)](https://www.sciencedirect.com/science/article/pii/S1364815216300287).\n", "3.[Douglas-Smith, D., Iwanaga, T., Croke, B. F. W. & Jakeman, A. J. Certain trends in uncertainty and sensitivity analysis: An overview of software tools and techniques. Environmental Modelling & Software 124, 104588 (2020)](https://doi.org/10.1007/978-1-4899-7547-8_5)\n", "4. [Knüsel, B. Epistemological Issues in Data-Driven Modeling in Climate Research. (ETH Zurich, 2020)](https://www.research-collection.ethz.ch/handle/20.500.11850/399735)\n", @@ -542,12 +542,12 @@ "source": [ "| Attribute | Type | Description |\n", "| --- | --- | --- |\n", - "| sampling_method | str | The sampling method as defined in [SALib](https://salib.readthedocs.io/en/latest/api.html). Possible choices: 'saltelli', 'fast_sampler', 'latin', 'morris', 'dgsm', 'ff'|\n", + "| sampling_method | str | The sampling method as defined in [SALib](https://salib.readthedocs.io/en/latest/api.html). Possible choices: 'saltelli', 'fast_sampler', 'latin', 'morris', 'dgsm', 'ff', 'finite_diff'|\n", "| sampling_kwargs | dict | Keyword arguments for the sampling_method. |\n", "| n_samples | int | Effective number of samples (number of rows of samples_df)|\n", "| param_labels | list(str) | Name of all the uncertainty input parameters|\n", "| problem_sa | dict | The description of the uncertainty variables and their distribution as used in [SALib](https://salib.readthedocs.io/en/latest/basics.html). |\n", - "| sensitivity_method | str | Sensitivity analysis method from [SALib.analyse](https://salib.readthedocs.io/en/latest/api.html) Possible choices: 'fast', 'rbd_fact', 'morris', 'sobol', 'delta', 'ff'. Note that in Salib, sampling methods and sensitivity analysis methods should be used in specific pairs.|\n", + "| sensitivity_method | str | Sensitivity analysis method from [SALib.analyse](https://salib.readthedocs.io/en/latest/api.html) Possible choices: 'sobol', 'fast', 'rbd_fast', 'morris', 'dgsm', 'ff', 'pawn', 'rhdm', 'rsa', 'discrepancy', 'hdmr'. Note that in Salib, sampling methods and sensitivity analysis methods should be used in specific pairs.|\n", "| sensitivity_kwargs | dict | Keyword arguments for sensitivity_method. |\n", "| unit | str | Unit of the exposures value |" ] @@ -2466,7 +2466,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -2475,10 +2475,10 @@ "haz.basin = [\"NA\"] * haz.size\n", "\n", "# apply climate change factors\n", - "haz_26 = haz.apply_climate_scenario_knu(ref_year=2050, rcp_scenario=26)\n", - "haz_45 = haz.apply_climate_scenario_knu(ref_year=2050, rcp_scenario=45)\n", - "haz_60 = haz.apply_climate_scenario_knu(ref_year=2050, rcp_scenario=60)\n", - "haz_85 = haz.apply_climate_scenario_knu(ref_year=2050, rcp_scenario=85)\n", + "haz_26 = haz.apply_climate_scenario_knu(target_year=2050, scenario=\"2.6\")\n", + "haz_45 = haz.apply_climate_scenario_knu(target_year=2050, scenario=\"4.5\")\n", + "haz_60 = haz.apply_climate_scenario_knu(target_year=2050, scenario=\"6.0\")\n", + "haz_85 = haz.apply_climate_scenario_knu(target_year=2050, scenario=\"8.5\")\n", "\n", "# pack future hazard sets into dictionary - we want to sample from this dictionary later\n", "haz_fut_list = [haz_26, haz_45, haz_60, haz_85]\n", @@ -2489,7 +2489,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -2501,7 +2501,7 @@ "\n", "def exp_base_func(x_exp, exp_base):\n", " exp = exp_base.copy()\n", - " exp.gdf[\"value\"] *= x_exp\n", + " exp.data[\"value\"] *= x_exp\n", " return exp\n", "\n", "\n", @@ -2821,7 +2821,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2023-08-03T12:00:12.180767Z", @@ -2844,7 +2844,7 @@ "\n", " entity = Entity.from_excel(ENT_DEMO_TODAY)\n", " entity.exposures.ref_year = 2018\n", - " entity.exposures.gdf[\"value\"] *= x_ent\n", + " entity.exposures.data[\"value\"] *= x_ent\n", " return entity\n", "\n", "\n", @@ -2954,7 +2954,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2023-08-03T12:00:12.959984Z", @@ -3070,7 +3070,7 @@ ], "source": [ "ent_avg = ent_today_iv.evaluate()\n", - "ent_avg.exposures.gdf.head()" + "ent_avg.exposures.data.head()" ] }, { @@ -5320,7 +5320,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -5335,7 +5335,7 @@ "\n", "def exp_func(cnt, x_exp, exp_list=exp_list):\n", " exp = exp_list[int(cnt)].copy()\n", - " exp.gdf[\"value\"] *= x_exp\n", + " exp.data[\"value\"] *= x_exp\n", " return exp\n", "\n", "\n", @@ -5523,7 +5523,7 @@ "source": [ "Loading Hazards or Exposures from file is a rather lengthy operation. Thus, we want to minimize the reading operations, ideally reading each file only once. Simultaneously, Hazard and Exposures can be large in memory, and thus we would like to have at most one of each loaded at a time. Thus, we do not want to use the list capacity from the helper method InputVar.exposures and InputVar.hazard.\n", "\n", - "For demonstration purposes, we will use below as exposures files the litpop for three countries, and for tha hazard files the winter storms for the same three countries. Note that this does not make a lot of sense for an uncertainty analysis. For your use case, please replace the set of exposures and/or hazard files with meaningful sets, for instance sets of exposures for different resolutions or hazards for different model runs.\n" + "For demonstration purposes, we will use below as exposures files the litpop for three countries, and for the hazard files the winter storms for the same three countries. Note that this does not make a lot of sense for an uncertainty analysis. For your use case, please replace the set of exposures and/or hazard files with meaningful sets, for instance sets of exposures for different resolutions or hazards for different model runs.\n" ] }, { @@ -5600,17 +5600,18 @@ "def exp_func(f_exp, x_exp, filename_list=f_exp_list):\n", " filename = filename_list[int(f_exp)]\n", " global exp_base\n", - " if \"exp_base\" in globals():\n", - " if isinstance(exp_base, Exposures):\n", - " if exp_base.gdf[\"filename\"] != str(filename):\n", - " exp_base = Exposures.from_hdf5(filename)\n", - " exp_base.gdf[\"filename\"] = str(filename)\n", + " if (\n", + " \"exp_base\" in globals()\n", + " and isinstance(exp_base, Exposures)\n", + " and exp_base.description == str(filename)\n", + " ):\n", + " pass # if correct file is already loaded in memory, we do not need to reload it\n", " else:\n", " exp_base = Exposures.from_hdf5(filename)\n", - " exp_base.gdf[\"filename\"] = str(filename)\n", + " exp_base.description = str(filename)\n", "\n", " exp = exp_base.copy()\n", - " exp.gdf[\"value\"] *= x_exp\n", + " exp.data[\"value\"] *= x_exp\n", " return exp\n", "\n", "\n", @@ -5624,14 +5625,16 @@ "def haz_func(f_haz, i_haz, filename_list=f_haz_list):\n", " filename = filename_list[int(f_haz)]\n", " global haz_base\n", - " if \"haz_base\" in globals():\n", - " if isinstance(haz_base, Hazard):\n", - " if haz_base.filename != str(filename):\n", - " haz_base = Hazard.from_hdf5(filename)\n", - " haz_base.filename = str(filename)\n", + " if (\n", + " \"haz_base\" in globals()\n", + " and isinstance(haz_base, Hazard)\n", + " and hasattr(haz_base, \"description\")\n", + " and haz_base.description == str(filename)\n", + " ):\n", + " pass\n", " else:\n", " haz_base = Hazard.from_hdf5(filename)\n", - " haz_base.filename = str(filename)\n", + " setattr(haz_base, \"description\", str(filename))\n", "\n", " haz = copy.deepcopy(haz_base)\n", " haz.intensity *= i_haz\n", @@ -5707,7 +5710,7 @@ "source": [ "# Ordering of the samples by hazard first and exposures second\n", "output_imp = calc_imp.make_sample(N=2**2, sampling_kwargs={\"skip_values\": 2**3})\n", - "output_imp.order_samples(by=[\"f_haz\", \"f_exp\"])" + "output_imp.order_samples(by_parameters=[\"f_haz\", \"f_exp\"])" ] }, { diff --git a/doc/user-guide/climada_engine_unsequa_helper.ipynb b/doc/user-guide/climada_engine_unsequa_helper.ipynb index adad223232..f246b539d1 100644 --- a/doc/user-guide/climada_engine_unsequa_helper.ipynb +++ b/doc/user-guide/climada_engine_unsequa_helper.ipynb @@ -67,8 +67,7 @@ "- EN: mutliplicative noise (inhomogeneous)\n", "> The value of each exposure point is independently multiplied by a random number sampled uniformly from a distribution with (min, max) = bounds_noise. EN is the value of the seed for the uniform random number generator.\n", "- EL: sample uniformly from exposure list\n", - "> From the provided list of exposure is elements are uniformly sampled. For example, LitPop instances with different exponents.\n", - "\n", + "> For each sample, one element is drawn uniformly from the provided list of exposures. For example, LitPop instances with different exponents.\n", "\n", "If a bounds is None, this parameter is assumed to have no uncertainty." ] @@ -201,7 +200,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "802ac379-39a0-476d-b068-36520d03a459", "metadata": { "ExecuteTime": { @@ -226,8 +225,8 @@ " print(\"\\n Computing litpop for m=%d, n=%d \\n\" % (m, n))\n", " litpop_kwargs[\"exponents\"] = (m, n)\n", " exp = LitPop.from_countries(**litpop_kwargs)\n", - " exp.gdf[\"impf_\" + haz.haz_type] = impf_id\n", - " exp.gdf.drop(\"impf_\", axis=1, inplace=True)\n", + " exp.data[\"impf_\" + haz.haz_type] = impf_id\n", + " exp.data.drop(\"impf_\", axis=1, inplace=True)\n", " if value_unit is not None:\n", " exp.value_unit = value_unit\n", " exp.assign_centroids(haz, **assign_centr_kwargs)\n", @@ -897,7 +896,7 @@ "- HF: scale the frequency of all events (homogeneously)\n", "> The frequency of all events is multiplied by a number sampled uniformly from a distribution with (min, max) = bounds_freq\n", "- HL: sample uniformly from hazard list\n", - "> From the provided list of hazard is elements are uniformly sampled. For example, Hazards outputs from dynamical models for different input factors.\n", + "> Uniformly sample one element from the provided list of hazards. For example, Hazards outputs from dynamical models for different input factors.\n", "\n", "If a bounds is None, this parameter is assumed to have no uncertainty." ] @@ -1146,15 +1145,14 @@ }, "source": [ "The following types of uncertainties can be added:\n", - "- MDD: scale the mdd (homogeneously)\n", + "- MDD: scale the Mean Damage Degree MDD (homogeneously)\n", "> The value of mdd at each intensity is multiplied by a number sampled uniformly from a distribution with (min, max) = bounds_mdd\n", - "- PAA: scale the paa (homogeneously)\n", + "- PAA: scale the Percentage of Affected Assets PAA (homogeneously)\n", "> The value of paa at each intensity is multiplied by a number sampled uniformly from a distribution with (min, max) = bounds_paa\n", "- IFi: shift the intensity (homogeneously)\n", "> The value intensity are all summed with a random number sampled uniformly from a distribution with (min, max) = bounds_int\n", "- IL: sample uniformly from impact function set list\n", - "> From the provided list of impact function sets elements are uniformly sampled. For example, impact functions obtained from different calibration methods.\n", - "\n", + "> For each sample, one element is drawn uniformly from the provided list of impact function sets. For example, impact functions obtained from different calibration methods.\n", "\n", "If a bounds is None, this parameter is assumed to have no uncertainty." ] @@ -1268,13 +1266,15 @@ "- EN: mutliplicative noise (inhomogeneous)\n", "> The value of each exposure point is independently multiplied by a random number sampled uniformly from a distribution with (min, max) = bounds_noise. EN is the value of the seed for the uniform random number generator.\n", "- EL: sample uniformly from exposure list\n", - "> From the provided list of exposure is elements are uniformly sampled. For example, LitPop instances with different exponents.\n", + "> For each sample, one element is drawn uniformly from the provided list of exposures. For example, LitPop instances with different exponents.\n", "- MDD: scale the mdd (homogeneously)\n", "> The value of mdd at each intensity is multiplied by a number sampled uniformly from a distribution with (min, max) = bounds_mdd\n", "- PAA: scale the paa (homogeneously)\n", "> The value of paa at each intensity is multiplied by a number sampled uniformly from a distribution with (min, max) = bounds_paa\n", "- IFi: shift the intensity (homogeneously)\n", "> The value intensity are all summed with a random number sampled uniformly from a distribution with (min, max) = bounds_int\n", + "- IL: sample uniformly from impact function set list\n", + "> For each sample, one element is drawn uniformly from the provided list of impact function sets. For example, impact functions obtained from different calibration methods.\n", "\n", "\n", "If a bounds is None, this parameter is assumed to have no uncertainty." @@ -1819,7 +1819,7 @@ "- EN: mutliplicative noise (inhomogeneous)\n", "> The value of each exposure point is independently multiplied by a random number sampled uniformly from a distribution with (min, max) = bounds_noise. EN is the value of the seed for the uniform random number generator.\n", "- EL: sample uniformly from exposure list\n", - "> From the provided list of exposure is elements are uniformly sampled. For example, LitPop instances with different exponents.\n", + "> For each sample, one element is drawn uniformly from the provided list of exposures. For example, LitPop instances with different exponents.\n", "- MDD: scale the mdd (homogeneously)\n", "> The value of mdd at each intensity is multiplied by a number sampled uniformly from a distribution with (min, max) = bounds_mdd\n", "- PAA: scale the paa (homogeneously)\n", @@ -1827,8 +1827,7 @@ "- IFi: shift the impact function intensity (homogeneously)\n", "> The value intensity are all summed with a random number sampled uniformly from a distribution with (min, max) = bounds_impfi\n", "- IL: sample uniformly from impact function set list\n", - "> From the provided list of impact function sets elements are uniformly sampled. For example, impact functions obtained from different calibration methods.\n", - "\n", + "> For each sample, one element is drawn uniformly from the provided list of impact function sets. For example, impact functions obtained from different calibration methods.\n", "\n", "If a bounds is None, this parameter is assumed to have no uncertainty." ]