From afb0e9d54edbd101b6295f7d37e30d1ba2222993 Mon Sep 17 00:00:00 2001 From: davidrzhdu Date: Mon, 21 Aug 2023 14:42:05 -0700 Subject: [PATCH 01/12] make quantreg run with statistical uncertainty --- src/dscim/menu/main_recipe.py | 9 ++++++++- src/dscim/utils/utils.py | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/dscim/menu/main_recipe.py b/src/dscim/menu/main_recipe.py index b7adafb2..2faeeb4a 100644 --- a/src/dscim/menu/main_recipe.py +++ b/src/dscim/menu/main_recipe.py @@ -1121,7 +1121,14 @@ def discounted_damages(self, damages, discrate): def uncollapsed_sccs(self): """Calculate full distribution of SCCs without FAIR aggregation""" - md = self.global_consumption_no_pulse - self.global_consumption_pulse + if (self.fit_type == "quantreg") & ("median_params" in self.fair_aggregation): + md = ( + self.median_params_marginal_damages + ) # this is for statistical uncertainty + else: + md = ( + self.global_consumption_no_pulse - self.global_consumption_pulse + ) # this is for full uncertainty # convert to the marginal damages from a single pulse md = md * self.climate.conversion diff --git a/src/dscim/utils/utils.py b/src/dscim/utils/utils.py index fce23a58..570908fc 100644 --- a/src/dscim/utils/utils.py +++ b/src/dscim/utils/utils.py @@ -112,6 +112,10 @@ def quantile_weight_quantilereg(array, quantiles=None): if quantiles is None: quantiles = [0.01, 0.05, 0.167, 0.25, 0.5, 0.75, 0.833, 0.95, 0.99] + if "simulation" not in array.coords: + array = array.assign_coords(simulation=1) + array = array.expand_dims(dim="simulation") + qr_quantiles = array.q.values weights = xr.DataArray(get_weights(qr_quantiles), dims=["q"], coords=[qr_quantiles]) From 2d8d3223194a89205d3ea586c2b99e5e6932fd36 Mon Sep 17 00:00:00 2001 From: davidrzhdu Date: Tue, 3 Oct 2023 09:24:22 -0700 Subject: [PATCH 02/12] update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eff264c9..649ac8d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Add naive list of package dependencies to pyproject.toml.([PR #123](https://github.com/ClimateImpactLab/dscim/pull/123), [@brews](https://github.com/brews)) +- Add an option for producing SCC ranges that account for statistical uncertainty. ([PR #143](https://github.com/ClimateImpactLab/dscim/pull/143), [@davidrzhdu](https://github.com/davidrzhdu)) ### Changed From 7b3ce136c19d57bec57d291553daaccbbaa9e2b3 Mon Sep 17 00:00:00 2001 From: JMGilbert Date: Wed, 31 Jan 2024 14:52:55 -0600 Subject: [PATCH 03/12] Generalize quantile_weight_quantilereg and add tests --- src/dscim/menu/main_recipe.py | 2 +- src/dscim/utils/utils.py | 17 +++--- tests/test_fair_utils.py | 97 +++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 8 deletions(-) diff --git a/src/dscim/menu/main_recipe.py b/src/dscim/menu/main_recipe.py index 2faeeb4a..660f61e5 100644 --- a/src/dscim/menu/main_recipe.py +++ b/src/dscim/menu/main_recipe.py @@ -1121,7 +1121,7 @@ def discounted_damages(self, damages, discrate): def uncollapsed_sccs(self): """Calculate full distribution of SCCs without FAIR aggregation""" - if (self.fit_type == "quantreg") & ("median_params" in self.fair_aggregation): + if (self.fit_type == "quantreg") and ("median_params" in self.fair_aggregation): md = ( self.median_params_marginal_damages ) # this is for statistical uncertainty diff --git a/src/dscim/utils/utils.py b/src/dscim/utils/utils.py index 22ce7166..e2b3746b 100644 --- a/src/dscim/utils/utils.py +++ b/src/dscim/utils/utils.py @@ -99,7 +99,7 @@ def get_weights(quantiles): return weights -def quantile_weight_quantilereg(array, quantiles=None): +def quantile_weight_quantilereg(array, fair_dims, quantiles=None): """Produce quantile weights of the quantile regression damages. Parameters @@ -112,15 +112,18 @@ def quantile_weight_quantilereg(array, quantiles=None): if quantiles is None: quantiles = [0.01, 0.05, 0.167, 0.25, 0.5, 0.75, 0.833, 0.95, 0.99] - if "simulation" not in array.coords: - array = array.assign_coords(simulation=1) - array = array.expand_dims(dim="simulation") - qr_quantiles = array.q.values weights = xr.DataArray(get_weights(qr_quantiles), dims=["q"], coords=[qr_quantiles]) - ds_stacked = array.stack(obs=("simulation", "q")) - weights_by_obs = weights.sel(q=ds_stacked.obs.q) + to_stack = ["q"] + list(set(fair_dims).intersection(set(array.coords))) + + if len(to_stack) > 1: + ds_stacked = array.stack(obs=to_stack) + weights_by_obs = weights.sel(q=ds_stacked.obs.q) + else: + ds_stacked = array.rename({to_stack[0]:"obs"}) + weights_by_obs = weights.sel(q=ds_stacked.obs) + dim = "obs" # these are quantiles of the statistical or full uncertainty, weighted by the quantile regression quantiles diff --git a/tests/test_fair_utils.py b/tests/test_fair_utils.py index 43b20dca..a8395e96 100644 --- a/tests/test_fair_utils.py +++ b/tests/test_fair_utils.py @@ -1,9 +1,11 @@ import numpy as np import pandas as pd +import xarray as xr import pytest import statsmodels.formula.api as smf from dscim.utils.utils import modeler from dscim.utils.utils import get_weights +from dscim.utils.utils import quantile_weight_quantilereg def test_modeler(): @@ -57,3 +59,98 @@ def test_get_weights(): ) np.testing.assert_allclose(get_weights([1]), np.array([1])) np.testing.assert_allclose(get_weights([0]), np.array([1])) + +def test_quantile_weight_quantilereg_dim(): + """ + input cases covered : + fair dim is included in uncollapsed_sccs + """ + ds_in = xr.Dataset( + { + 'uncollapsed_sccs': ( + ["discount_type", "model", "ssp", "rcp", "simulation", "gas", "q", "weitzman_parameter", "fair_aggregation"], + np.ones((1, 2, 2, 2, 5, 1, 3, 1, 1)), + ), + }, + coords={ + "discount_type": (["discount_type"], ["Euler_Ramsey"]), + "model": (["model"], ["IIASA GDP", "OECD Env-Growth"]), + "ssp": (["ssp"], ["SSP3", "SSP4"]), + "rcp": (["rcp"], ["rcp245", "rcp585"]), + "simulation": (["simulation"], [0,1,2,3,4]), + "gas": (["gas"], ["CO2_Fossil"]), + "q": (["q"], [0.01, 0.5, 0.99]), + "weitzman_parameter": (["weitzman_parameter"], ["0.1"]), + "fair_aggregation": (["fair_aggregation"], ["uncollapsed"]), + }, + ) + + ds_out = quantile_weight_quantilereg(ds_in.uncollapsed_sccs, ["simulation"], quantiles=[0.01,0.5,0.99]) + + ds_out_expected = xr.Dataset( + { + 'uncollapsed_sccs': ( + ["discount_type", "model", "ssp", "rcp", "simulation", "gas", "q", "weitzman_parameter", "fair_aggregation"], + np.ones((1, 2, 2, 2, 5, 1, 3, 1, 1)), + ), + }, + coords={ + "discount_type": (["discount_type"], ["Euler_Ramsey"]), + "model": (["model"], ["IIASA GDP", "OECD Env-Growth"]), + "ssp": (["ssp"], ["SSP3", "SSP4"]), + "rcp": (["rcp"], ["rcp245", "rcp585"]), + "gas": (["gas"], ["CO2_Fossil"]), + "weitzman_parameter": (["weitzman_parameter"], ["0.1"]), + "fair_aggregation": (["fair_aggregation"], ["uncollapsed"]), + "quantile": (["quantile"], [0.01,0.5,0.99]) + }, + ) + + np.testing.assert_equal(ds_out,ds_out_expected) + +def test_quantile_weight_quantilereg_nodim(): + """ + input cases covered : + fair dim is included in not included in uncollapsed_sccs + """ + ds_in = xr.Dataset( + { + 'uncollapsed_sccs': ( + ["discount_type", "model", "ssp", "rcp", "gas", "q", "weitzman_parameter", "fair_aggregation"], + np.ones((1, 2, 2, 2, 1, 3, 1, 1)), + ), + }, + coords={ + "discount_type": (["discount_type"], ["Euler_Ramsey"]), + "model": (["model"], ["IIASA GDP", "OECD Env-Growth"]), + "ssp": (["ssp"], ["SSP3", "SSP4"]), + "rcp": (["rcp"], ["rcp245", "rcp585"]), + "gas": (["gas"], ["CO2_Fossil"]), + "q": (["q"], [0.01, 0.5, 0.99]), + "weitzman_parameter": (["weitzman_parameter"], ["0.1"]), + "fair_aggregation": (["fair_aggregation"], ["uncollapsed"]), + }, + ) + + ds_out = quantile_weight_quantilereg(ds_in.uncollapsed_sccs, ["simulation"], quantiles=[0.01,0.5,0.99]) + + ds_out_expected = xr.Dataset( + { + 'uncollapsed_sccs': ( + ["discount_type", "model", "ssp", "rcp", "simulation", "gas", "q", "weitzman_parameter", "fair_aggregation"], + np.ones((1, 2, 2, 2, 5, 1, 3, 1, 1)), + ), + }, + coords={ + "discount_type": (["discount_type"], ["Euler_Ramsey"]), + "model": (["model"], ["IIASA GDP", "OECD Env-Growth"]), + "ssp": (["ssp"], ["SSP3", "SSP4"]), + "rcp": (["rcp"], ["rcp245", "rcp585"]), + "gas": (["gas"], ["CO2_Fossil"]), + "weitzman_parameter": (["weitzman_parameter"], ["0.1"]), + "fair_aggregation": (["fair_aggregation"], ["uncollapsed"]), + "quantile": (["quantile"], [0.01,0.5,0.99]) + }, + ) + + np.testing.assert_equal(ds_out,ds_out_expected) \ No newline at end of file From 11f6d7ff4ceb7dc5b1acf4a8b09f71b1f62738ab Mon Sep 17 00:00:00 2001 From: JMGilbert Date: Wed, 31 Jan 2024 15:52:28 -0600 Subject: [PATCH 04/12] black --- src/dscim/utils/utils.py | 4 +- tests/test_fair_utils.py | 205 ++++++++++++++++++++++++--------------- 2 files changed, 127 insertions(+), 82 deletions(-) diff --git a/src/dscim/utils/utils.py b/src/dscim/utils/utils.py index e2b3746b..540089fb 100644 --- a/src/dscim/utils/utils.py +++ b/src/dscim/utils/utils.py @@ -121,9 +121,9 @@ def quantile_weight_quantilereg(array, fair_dims, quantiles=None): ds_stacked = array.stack(obs=to_stack) weights_by_obs = weights.sel(q=ds_stacked.obs.q) else: - ds_stacked = array.rename({to_stack[0]:"obs"}) + ds_stacked = array.rename({to_stack[0]: "obs"}) weights_by_obs = weights.sel(q=ds_stacked.obs) - + dim = "obs" # these are quantiles of the statistical or full uncertainty, weighted by the quantile regression quantiles diff --git a/tests/test_fair_utils.py b/tests/test_fair_utils.py index a8395e96..6f434de6 100644 --- a/tests/test_fair_utils.py +++ b/tests/test_fair_utils.py @@ -60,97 +60,142 @@ def test_get_weights(): np.testing.assert_allclose(get_weights([1]), np.array([1])) np.testing.assert_allclose(get_weights([0]), np.array([1])) + def test_quantile_weight_quantilereg_dim(): """ input cases covered : fair dim is included in uncollapsed_sccs """ ds_in = xr.Dataset( - { - 'uncollapsed_sccs': ( - ["discount_type", "model", "ssp", "rcp", "simulation", "gas", "q", "weitzman_parameter", "fair_aggregation"], - np.ones((1, 2, 2, 2, 5, 1, 3, 1, 1)), - ), - }, - coords={ - "discount_type": (["discount_type"], ["Euler_Ramsey"]), - "model": (["model"], ["IIASA GDP", "OECD Env-Growth"]), - "ssp": (["ssp"], ["SSP3", "SSP4"]), - "rcp": (["rcp"], ["rcp245", "rcp585"]), - "simulation": (["simulation"], [0,1,2,3,4]), - "gas": (["gas"], ["CO2_Fossil"]), - "q": (["q"], [0.01, 0.5, 0.99]), - "weitzman_parameter": (["weitzman_parameter"], ["0.1"]), - "fair_aggregation": (["fair_aggregation"], ["uncollapsed"]), - }, - ) - - ds_out = quantile_weight_quantilereg(ds_in.uncollapsed_sccs, ["simulation"], quantiles=[0.01,0.5,0.99]) - + { + "uncollapsed_sccs": ( + [ + "discount_type", + "model", + "ssp", + "rcp", + "simulation", + "gas", + "q", + "weitzman_parameter", + "fair_aggregation", + ], + np.ones((1, 2, 2, 2, 5, 1, 3, 1, 1)), + ), + }, + coords={ + "discount_type": (["discount_type"], ["Euler_Ramsey"]), + "model": (["model"], ["IIASA GDP", "OECD Env-Growth"]), + "ssp": (["ssp"], ["SSP3", "SSP4"]), + "rcp": (["rcp"], ["rcp245", "rcp585"]), + "simulation": (["simulation"], [0, 1, 2, 3, 4]), + "gas": (["gas"], ["CO2_Fossil"]), + "q": (["q"], [0.01, 0.5, 0.99]), + "weitzman_parameter": (["weitzman_parameter"], ["0.1"]), + "fair_aggregation": (["fair_aggregation"], ["uncollapsed"]), + }, + ) + + ds_out = quantile_weight_quantilereg( + ds_in.uncollapsed_sccs, ["simulation"], quantiles=[0.01, 0.5, 0.99] + ) + ds_out_expected = xr.Dataset( - { - 'uncollapsed_sccs': ( - ["discount_type", "model", "ssp", "rcp", "simulation", "gas", "q", "weitzman_parameter", "fair_aggregation"], - np.ones((1, 2, 2, 2, 5, 1, 3, 1, 1)), - ), - }, - coords={ - "discount_type": (["discount_type"], ["Euler_Ramsey"]), - "model": (["model"], ["IIASA GDP", "OECD Env-Growth"]), - "ssp": (["ssp"], ["SSP3", "SSP4"]), - "rcp": (["rcp"], ["rcp245", "rcp585"]), - "gas": (["gas"], ["CO2_Fossil"]), - "weitzman_parameter": (["weitzman_parameter"], ["0.1"]), - "fair_aggregation": (["fair_aggregation"], ["uncollapsed"]), - "quantile": (["quantile"], [0.01,0.5,0.99]) - }, - ) - - np.testing.assert_equal(ds_out,ds_out_expected) - + { + "uncollapsed_sccs": ( + [ + "discount_type", + "model", + "ssp", + "rcp", + "simulation", + "gas", + "q", + "weitzman_parameter", + "fair_aggregation", + ], + np.ones((1, 2, 2, 2, 5, 1, 3, 1, 1)), + ), + }, + coords={ + "discount_type": (["discount_type"], ["Euler_Ramsey"]), + "model": (["model"], ["IIASA GDP", "OECD Env-Growth"]), + "ssp": (["ssp"], ["SSP3", "SSP4"]), + "rcp": (["rcp"], ["rcp245", "rcp585"]), + "gas": (["gas"], ["CO2_Fossil"]), + "weitzman_parameter": (["weitzman_parameter"], ["0.1"]), + "fair_aggregation": (["fair_aggregation"], ["uncollapsed"]), + "quantile": (["quantile"], [0.01, 0.5, 0.99]), + }, + ) + + np.testing.assert_equal(ds_out, ds_out_expected) + + def test_quantile_weight_quantilereg_nodim(): """ input cases covered : fair dim is included in not included in uncollapsed_sccs """ ds_in = xr.Dataset( - { - 'uncollapsed_sccs': ( - ["discount_type", "model", "ssp", "rcp", "gas", "q", "weitzman_parameter", "fair_aggregation"], - np.ones((1, 2, 2, 2, 1, 3, 1, 1)), - ), - }, - coords={ - "discount_type": (["discount_type"], ["Euler_Ramsey"]), - "model": (["model"], ["IIASA GDP", "OECD Env-Growth"]), - "ssp": (["ssp"], ["SSP3", "SSP4"]), - "rcp": (["rcp"], ["rcp245", "rcp585"]), - "gas": (["gas"], ["CO2_Fossil"]), - "q": (["q"], [0.01, 0.5, 0.99]), - "weitzman_parameter": (["weitzman_parameter"], ["0.1"]), - "fair_aggregation": (["fair_aggregation"], ["uncollapsed"]), - }, - ) - - ds_out = quantile_weight_quantilereg(ds_in.uncollapsed_sccs, ["simulation"], quantiles=[0.01,0.5,0.99]) - + { + "uncollapsed_sccs": ( + [ + "discount_type", + "model", + "ssp", + "rcp", + "gas", + "q", + "weitzman_parameter", + "fair_aggregation", + ], + np.ones((1, 2, 2, 2, 1, 3, 1, 1)), + ), + }, + coords={ + "discount_type": (["discount_type"], ["Euler_Ramsey"]), + "model": (["model"], ["IIASA GDP", "OECD Env-Growth"]), + "ssp": (["ssp"], ["SSP3", "SSP4"]), + "rcp": (["rcp"], ["rcp245", "rcp585"]), + "gas": (["gas"], ["CO2_Fossil"]), + "q": (["q"], [0.01, 0.5, 0.99]), + "weitzman_parameter": (["weitzman_parameter"], ["0.1"]), + "fair_aggregation": (["fair_aggregation"], ["uncollapsed"]), + }, + ) + + ds_out = quantile_weight_quantilereg( + ds_in.uncollapsed_sccs, ["simulation"], quantiles=[0.01, 0.5, 0.99] + ) + ds_out_expected = xr.Dataset( - { - 'uncollapsed_sccs': ( - ["discount_type", "model", "ssp", "rcp", "simulation", "gas", "q", "weitzman_parameter", "fair_aggregation"], - np.ones((1, 2, 2, 2, 5, 1, 3, 1, 1)), - ), - }, - coords={ - "discount_type": (["discount_type"], ["Euler_Ramsey"]), - "model": (["model"], ["IIASA GDP", "OECD Env-Growth"]), - "ssp": (["ssp"], ["SSP3", "SSP4"]), - "rcp": (["rcp"], ["rcp245", "rcp585"]), - "gas": (["gas"], ["CO2_Fossil"]), - "weitzman_parameter": (["weitzman_parameter"], ["0.1"]), - "fair_aggregation": (["fair_aggregation"], ["uncollapsed"]), - "quantile": (["quantile"], [0.01,0.5,0.99]) - }, - ) - - np.testing.assert_equal(ds_out,ds_out_expected) \ No newline at end of file + { + "uncollapsed_sccs": ( + [ + "discount_type", + "model", + "ssp", + "rcp", + "simulation", + "gas", + "q", + "weitzman_parameter", + "fair_aggregation", + ], + np.ones((1, 2, 2, 2, 5, 1, 3, 1, 1)), + ), + }, + coords={ + "discount_type": (["discount_type"], ["Euler_Ramsey"]), + "model": (["model"], ["IIASA GDP", "OECD Env-Growth"]), + "ssp": (["ssp"], ["SSP3", "SSP4"]), + "rcp": (["rcp"], ["rcp245", "rcp585"]), + "gas": (["gas"], ["CO2_Fossil"]), + "weitzman_parameter": (["weitzman_parameter"], ["0.1"]), + "fair_aggregation": (["fair_aggregation"], ["uncollapsed"]), + "quantile": (["quantile"], [0.01, 0.5, 0.99]), + }, + ) + + np.testing.assert_equal(ds_out, ds_out_expected) From d0d7f0d2c3dcd77c1c99049d3ec5d2a7ac9f76f9 Mon Sep 17 00:00:00 2001 From: Jonah Gilbert Date: Thu, 22 Feb 2024 13:08:39 -0800 Subject: [PATCH 05/12] Fix issue with improper fair_dims --- src/dscim/menu/main_recipe.py | 28 ++++++++++++++++------------ src/dscim/utils/utils.py | 2 +- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/dscim/menu/main_recipe.py b/src/dscim/menu/main_recipe.py index 660f61e5..d5897726 100644 --- a/src/dscim/menu/main_recipe.py +++ b/src/dscim/menu/main_recipe.py @@ -318,6 +318,8 @@ def scc(): self.logger.info("Processing SCC calculation ...") if self.fit_type == "quantreg": self.full_uncertainty_iqr + self.calculate_scc + self.quantiles_sccs else: if len(self.fair_aggregation) > 0: self.stream_discount_factors @@ -1121,14 +1123,9 @@ def discounted_damages(self, damages, discrate): def uncollapsed_sccs(self): """Calculate full distribution of SCCs without FAIR aggregation""" - if (self.fit_type == "quantreg") and ("median_params" in self.fair_aggregation): - md = ( - self.median_params_marginal_damages - ) # this is for statistical uncertainty - else: - md = ( - self.global_consumption_no_pulse - self.global_consumption_pulse - ) # this is for full uncertainty + md = ( + self.global_consumption_no_pulse - self.global_consumption_pulse + ) # this is for full uncertainty # convert to the marginal damages from a single pulse md = md * self.climate.conversion @@ -1142,9 +1139,14 @@ def uncollapsed_sccs(self): return sccs - # @cachedproperty - # def quantiles_sccs(self): - # return self.uncollapsed_sccs.quantile(self.scc_quantiles, dim=self.fair_dims) + @cachedproperty + @save(name="quantiles_sccs") + def quantiles_sccs(self): + return quantile_weight_quantilereg( + self.calculate_scc, + fair_dims=self.fair_dims, + quantiles=self.full_uncertainty_quantiles, + ) @cachedproperty @save(name="full_uncertainty_iqr") @@ -1153,7 +1155,9 @@ def full_uncertainty_iqr(self): quantile regressions. """ return quantile_weight_quantilereg( - self.uncollapsed_sccs, quantiles=self.full_uncertainty_quantiles + self.uncollapsed_sccs, + fair_dims=[], + quantiles=self.full_uncertainty_quantiles, ) def calculate_discount_factors(self, cons_pc): diff --git a/src/dscim/utils/utils.py b/src/dscim/utils/utils.py index 540089fb..c027a652 100644 --- a/src/dscim/utils/utils.py +++ b/src/dscim/utils/utils.py @@ -113,9 +113,9 @@ def quantile_weight_quantilereg(array, fair_dims, quantiles=None): quantiles = [0.01, 0.05, 0.167, 0.25, 0.5, 0.75, 0.833, 0.95, 0.99] qr_quantiles = array.q.values - weights = xr.DataArray(get_weights(qr_quantiles), dims=["q"], coords=[qr_quantiles]) to_stack = ["q"] + list(set(fair_dims).intersection(set(array.coords))) + weights = xr.DataArray(get_weights(qr_quantiles), dims=["q"], coords=[qr_quantiles]) if len(to_stack) > 1: ds_stacked = array.stack(obs=to_stack) From 59b8ccd1f4964b69f13c2981ed1f8a08cf7d8164 Mon Sep 17 00:00:00 2001 From: Jonah Gilbert Date: Mon, 26 Feb 2024 11:50:29 -0600 Subject: [PATCH 06/12] Fix typo in docstr --- tests/test_fair_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_fair_utils.py b/tests/test_fair_utils.py index 6f434de6..07e655e0 100644 --- a/tests/test_fair_utils.py +++ b/tests/test_fair_utils.py @@ -135,7 +135,7 @@ def test_quantile_weight_quantilereg_dim(): def test_quantile_weight_quantilereg_nodim(): """ input cases covered : - fair dim is included in not included in uncollapsed_sccs + fair dim is included in uncollapsed_sccs """ ds_in = xr.Dataset( { From c86cf36374dfd9964b617e3d6f17070a3965e3ca Mon Sep 17 00:00:00 2001 From: Jonah Gilbert Date: Tue, 27 Feb 2024 13:01:32 -0600 Subject: [PATCH 07/12] Update statistical uncertainty sccs --- src/dscim/menu/main_recipe.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dscim/menu/main_recipe.py b/src/dscim/menu/main_recipe.py index d5897726..f7bc4224 100644 --- a/src/dscim/menu/main_recipe.py +++ b/src/dscim/menu/main_recipe.py @@ -1140,8 +1140,8 @@ def uncollapsed_sccs(self): return sccs @cachedproperty - @save(name="quantiles_sccs") - def quantiles_sccs(self): + @save(name="stat_uncertainty_iqr") + def stat_uncertainty_iqr(self): return quantile_weight_quantilereg( self.calculate_scc, fair_dims=self.fair_dims, @@ -1156,7 +1156,7 @@ def full_uncertainty_iqr(self): """ return quantile_weight_quantilereg( self.uncollapsed_sccs, - fair_dims=[], + fair_dims=self.fair_dims, quantiles=self.full_uncertainty_quantiles, ) From 0534d1deb87b879157426ab9b18d1f8e4264f472 Mon Sep 17 00:00:00 2001 From: Jonah Gilbert Date: Tue, 27 Feb 2024 13:14:55 -0600 Subject: [PATCH 08/12] Fix reference to stat uncertainty scc --- src/dscim/menu/main_recipe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dscim/menu/main_recipe.py b/src/dscim/menu/main_recipe.py index f7bc4224..c01f1264 100644 --- a/src/dscim/menu/main_recipe.py +++ b/src/dscim/menu/main_recipe.py @@ -319,7 +319,7 @@ def scc(): if self.fit_type == "quantreg": self.full_uncertainty_iqr self.calculate_scc - self.quantiles_sccs + self.stat_uncertainty_iqr else: if len(self.fair_aggregation) > 0: self.stream_discount_factors From 8358074644350c4e9a31f07f313093dcb9a54c46 Mon Sep 17 00:00:00 2001 From: Jonah Gilbert Date: Wed, 6 Mar 2024 10:23:36 -0600 Subject: [PATCH 09/12] Add docstr --- src/dscim/menu/main_recipe.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dscim/menu/main_recipe.py b/src/dscim/menu/main_recipe.py index c01f1264..7e00cb50 100644 --- a/src/dscim/menu/main_recipe.py +++ b/src/dscim/menu/main_recipe.py @@ -1142,6 +1142,9 @@ def uncollapsed_sccs(self): @cachedproperty @save(name="stat_uncertainty_iqr") def stat_uncertainty_iqr(self): + """Calculate the distribution of quantile-weighted SCCs produced from + quantile regressions collapsed across pulse dimension. + """ return quantile_weight_quantilereg( self.calculate_scc, fair_dims=self.fair_dims, From c172752a3d2c41198e829428d40197e365beb85c Mon Sep 17 00:00:00 2001 From: JMGilbert Date: Wed, 20 Mar 2024 15:40:08 -0500 Subject: [PATCH 10/12] Update test docstr --- tests/test_fair_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_fair_utils.py b/tests/test_fair_utils.py index 07e655e0..09b84ea0 100644 --- a/tests/test_fair_utils.py +++ b/tests/test_fair_utils.py @@ -64,7 +64,7 @@ def test_get_weights(): def test_quantile_weight_quantilereg_dim(): """ input cases covered : - fair dim is included in uncollapsed_sccs + fair dim (simulation in this case) is included in uncollapsed_sccs """ ds_in = xr.Dataset( { @@ -135,7 +135,7 @@ def test_quantile_weight_quantilereg_dim(): def test_quantile_weight_quantilereg_nodim(): """ input cases covered : - fair dim is included in uncollapsed_sccs + fair dim (simulation in this case) is not included in uncollapsed_sccs """ ds_in = xr.Dataset( { From a07e92df0145667b4f3bcda1967968190db82223 Mon Sep 17 00:00:00 2001 From: Jonah Gilbert Date: Thu, 21 Mar 2024 15:17:38 -0500 Subject: [PATCH 11/12] Update docstr --- src/dscim/menu/main_recipe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dscim/menu/main_recipe.py b/src/dscim/menu/main_recipe.py index 7e00cb50..0ab531d7 100644 --- a/src/dscim/menu/main_recipe.py +++ b/src/dscim/menu/main_recipe.py @@ -1143,7 +1143,7 @@ def uncollapsed_sccs(self): @save(name="stat_uncertainty_iqr") def stat_uncertainty_iqr(self): """Calculate the distribution of quantile-weighted SCCs produced from - quantile regressions collapsed across pulse dimension. + quantile regressions that have already been collapsed across other dimensions to give statistical-only uncertainty. """ return quantile_weight_quantilereg( self.calculate_scc, From 1f0a756360c099024d8405cd78c9a177f15e65b5 Mon Sep 17 00:00:00 2001 From: Jonah Gilbert Date: Mon, 25 Mar 2024 16:43:15 -0500 Subject: [PATCH 12/12] Update CHANGELOG.md --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc821758..abf83e77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,13 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- Add an option for producing SCC ranges that account for statistical uncertainty. ([PR #143](https://github.com/ClimateImpactLab/dscim/pull/143), [@davidrzhdu](https://github.com/davidrzhdu)) + + ## [0.5.0] - 2023-11-17 ### Added - Add naive list of package dependencies to pyproject.toml.([PR #123](https://github.com/ClimateImpactLab/dscim/pull/123), [@brews](https://github.com/brews)) - CI, coverage, DOI badges on README. ([PR #134](https://github.com/ClimateImpactLab/dscim/pull/134), [@brews](https://github.com/brews)) -- Add an option for producing SCC ranges that account for statistical uncertainty. ([PR #143](https://github.com/ClimateImpactLab/dscim/pull/143), [@davidrzhdu](https://github.com/davidrzhdu)) ### Changed