-
Notifications
You must be signed in to change notification settings - Fork 1
Sensitivity #63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Sensitivity #63
Changes from all commits
dd0f2f6
5057edf
13c5e8c
c254777
39022da
f533117
f9bb1e2
0bcdf9d
9baa596
f49980e
ca5aa3a
4dd0905
1443886
cd7c722
70894ac
ee13007
cd77212
7b3cdbc
343f1dc
048376b
a0d3673
24100d0
b7957d8
522b5f7
01f297f
df1030d
0fc760b
df74a21
01d924d
6948b9b
f90b0bd
dc5256d
49541c7
f8286a5
d8f9d9e
ab13cc9
6dd1050
1cb6af3
d9b6def
f4d9da9
b27567b
03cd8e1
9f4d481
932e142
9e24131
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,30 +1,185 @@ | ||
| import copy | ||
| import os | ||
| from oemoflex.model.datapackage import EnergyDataPackage | ||
|
|
||
|
|
||
| class VariationGenerator: | ||
| def __init__(self, datapackage): | ||
| def index_same(df_a, df_b): | ||
| return df_a.index.equals(df_b.index) | ||
|
|
||
| self.base_datapackage = datapackage | ||
|
|
||
| def create_variations(self, variations, destination): | ||
| def data_same(df_a, df_b): | ||
| return df_a.equals(df_b) | ||
|
|
||
| for id, changes in variations.iterrows(): | ||
|
|
||
| dp = self.create_var(self.base_datapackage, changes) | ||
| def smaller_equal(df_a, df_b): | ||
|
jnnr marked this conversation as resolved.
|
||
| return (df_a < df_b).all() | ||
|
|
||
| variation_dir = os.path.join(destination, str(id)) | ||
|
|
||
| dp.to_csv_dir(variation_dir) | ||
| def get_diff(df_a, df_b): | ||
|
jnnr marked this conversation as resolved.
|
||
| # # pandas>1.1.0 | ||
| # diff = self.lb.compare(self.ub) | ||
| return ~((df_a == df_b) | ((df_a != df_a) & (df_b != df_b))) | ||
|
|
||
| def create_var(self, dp, changes): | ||
|
|
||
| _dp = copy.deepcopy(dp) | ||
| def diff_larger_eps(df_a, df_b, eps): | ||
|
jnnr marked this conversation as resolved.
|
||
| diff = get_diff(df_a, df_b) | ||
| df_diff = df_a.loc[diff] - df_b.loc[diff] | ||
| return abs(df_diff) > eps | ||
|
|
||
| changes = changes.to_dict() | ||
|
|
||
| for (resource, var_name), var_value in changes.items(): | ||
| class Sensitivity(object): | ||
| r""" | ||
| Accepts two DataFrames that are the same in index and most columns, but have different entries | ||
| in the column 'var_value'. The DataFrames describe lower and upper bound of a variation. With | ||
| these intervals, different sampling methods can be invoked. | ||
| """ | ||
| AUX_COLUMNS = ["carrier", "region", "tech", "type"] | ||
| VAR_VALUE = "var_value" | ||
|
jnnr marked this conversation as resolved.
|
||
|
|
||
| _dp.data[resource].loc[:, var_name] = var_value | ||
| def __init__(self, lb, ub, eps=1e-6): | ||
| self.lb = lb | ||
| self.ub = ub | ||
| self.eps = eps | ||
| self.sanity_check() | ||
|
|
||
| return _dp | ||
| def sanity_check(self): | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Decouple sample method and sanity check. |
||
| # assert index same | ||
| assert index_same(self.lb, self.ub), "Indexes of lb and ub are not the same." | ||
|
|
||
| # Assert that the data is different | ||
| assert not data_same( | ||
| self.lb, self.ub | ||
| ), "There is no difference between lb and ub." | ||
|
|
||
| # Assert that the auxiliary columns are the same | ||
| assert data_same( | ||
| self.lb.loc[:, self.AUX_COLUMNS], self.ub.loc[:, self.AUX_COLUMNS] | ||
| ) | ||
|
|
||
| # find the parameters that are different (comparing NaN) | ||
| diff = self.get_diff() | ||
|
|
||
| # assert lb <= ub | ||
| assert smaller_equal( | ||
| self.lb.loc[diff, self.VAR_VALUE], self.ub.loc[diff, self.VAR_VALUE] | ||
| ) | ||
|
|
||
| # assert that the difference is larger than eps | ||
|
|
||
| assert diff_larger_eps( | ||
| self.lb.loc[diff, self.VAR_VALUE], | ||
| self.ub.loc[diff, self.VAR_VALUE], | ||
| self.eps, | ||
| ).all(), f"The difference between lb and ub is lower than the defined minimum of {self.eps}" | ||
|
|
||
| def get_diff(self): | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Revise naming |
||
| return get_diff(self.lb.loc[:, self.VAR_VALUE], self.ub.loc[:, self.VAR_VALUE]) | ||
|
|
||
| def get_param(self): | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Revise naming |
||
| # get the parameters that are varied | ||
| param = self.lb.index[self.get_diff()] | ||
| return param | ||
|
|
||
| def get_linear_slide(self, n): | ||
|
|
||
| params = self.get_param() | ||
|
|
||
| # for each param, create n samples | ||
| samples = {} | ||
|
|
||
| for i in range(n): | ||
| sample = self.lb.copy() | ||
| slider = i / (n - 1) | ||
| sample.loc[params, "var_value"] = (1 - slider) * self.lb.loc[ | ||
| params, "var_value" | ||
| ] + slider * self.ub.loc[params, "var_value"] | ||
| sample_name = "sample_" + str(i) | ||
| samples[sample_name] = sample | ||
|
|
||
| return samples | ||
|
|
||
| def get_salib_samples(self, salib_method, **kwargs): | ||
|
|
||
| params = self.get_param() | ||
|
|
||
| problem = { | ||
| "num_vars": len(params), | ||
| "names": list(params), | ||
| "bounds": list( | ||
| zip(self.lb.loc[params, "var_value"], self.ub.loc[params, "var_value"]) | ||
| ), | ||
| } | ||
|
|
||
| samples = salib_method(problem, **kwargs) | ||
|
|
||
| full_samples = {} | ||
| for i, sample in enumerate(samples): | ||
| full_sample = self.lb.copy() | ||
| full_sample.loc[params, "var_value"] = sample | ||
| sample_name = "sample_" + str(i) | ||
| full_samples[sample_name] = full_sample | ||
|
|
||
| return full_samples | ||
|
|
||
|
|
||
| class EDPSensitivity(Sensitivity): | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be done more general. The above Sensitivity class does checking and sampling for a single dataframe. This class is supposed to do the same for DataFramePackages. The implementation takes some time to grasp - could be more transparent? |
||
| r""" | ||
| Accepts two EnergyDataPackages that are have different values. The Packages describe lower and | ||
| upper bound of a variation. With these intervals, different sampling methods can be invoked. | ||
| """ | ||
|
|
||
| def __init__(self, lb_edp, ub_edp, eps=1e-6): | ||
| self.lb_edp = lb_edp | ||
| self.ub_edp = ub_edp | ||
| self.eps = eps | ||
| self.check_if_stacked() | ||
| self.sanity_check() | ||
|
|
||
| def check_if_stacked(self): | ||
| if not (self.lb_edp.stacked and self.ub_edp.stacked): | ||
| raise AssertionError("EnergyDataPackages have to be stacked") | ||
|
|
||
| def get_lb(self): | ||
| return self.lb_edp.data["component"] | ||
|
|
||
| def set_lb(self, value): | ||
| self.lb_edp.data["component"] = value | ||
|
|
||
| def del_lb(self): | ||
| del self.lb_edp | ||
|
|
||
| def get_ub(self): | ||
| return self.ub_edp.data["component"] | ||
|
|
||
| def set_ub(self, value): | ||
| self.ub_edp.data["component"] = value | ||
|
|
||
| def del_ub(self): | ||
| del self.ub_edp | ||
|
|
||
| lb = property(get_lb, set_lb, del_lb) | ||
| ub = property(get_ub, set_ub, del_ub) | ||
|
|
||
| def wrap_sampling(self, sampling): | ||
| def wrapped_sampling(*args, **kwargs): | ||
| samples = sampling(*args, **kwargs) | ||
| for name, df in samples.items(): | ||
| edp = EnergyDataPackage( | ||
| name=name, | ||
| basepath=None, | ||
| rel_paths=self.lb_edp.rel_paths.copy(), | ||
| data=self.lb_edp.data.copy(), | ||
| components=None, | ||
| ) | ||
| edp.data["component"] = df | ||
| edp.stacked = True | ||
| edp.metadata = self.lb_edp.metadata | ||
| samples[name] = edp | ||
|
|
||
| return samples | ||
|
|
||
| return wrapped_sampling | ||
|
|
||
| def get_linear_slide(self, n): | ||
| return self.wrap_sampling(super().get_linear_slide)(n) | ||
|
|
||
| def get_salib_samples(self, salib_method, **kwargs): | ||
| return self.wrap_sampling(super().get_salib_samples)(salib_method, **kwargs) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| name,capacity,capacity_cost,carrier,carrier_cost,efficiency,expandable,from_bus,marginal_cost,output_parameters,region,tech,to_bus,type | ||
| BB-biomass-st,400000,,biomass,0.040999999999999995,0.38,False,BB-biomass,0.0014,{},BB,gt,BB-electricity,conversion | ||
| BE-biomass-st,0,,biomass,0.040999999999999995,0.38,False,BE-biomass,0.0014,{},BE,gt,BE-electricity,conversion |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| region,name,type,balanced | ||
| BE,BE-electricity,bus,True | ||
| BE,BE-ch4,bus,False | ||
| BE,BE-oil,bus,False | ||
| BE,BE-other,bus,False | ||
| BE,BE-biomass,bus,False | ||
| BB,BB-electricity,bus,True | ||
| BB,BB-ch4,bus,False | ||
| BB,BB-oil,bus,False | ||
| BB,BB-other,bus,False | ||
| BB,BB-biomass,bus,False |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| name,capacity,capacity_cost,carrier,carrier_cost,efficiency,expandable,from_bus,marginal_cost,output_parameters,region,tech,to_bus,type | ||
| BB-ch4-gt,600000,,ch4,0.021,0.619,False,BB-ch4,0.0045,{},BB,gt,BB-electricity,conversion | ||
| BE-ch4-gt,1500000,,ch4,0.021,0.619,False,BE-ch4,0.0045,{},BE,gt,BE-electricity,conversion |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| name,bus,capacity,carrier,marginal_cost,output_parameters,region,tech,type | ||
| BB-electricity-curtailment,BB-electricity,,electricity,0,{},BB,curtailment,excess | ||
| BE-electricity-curtailment,BE-electricity,,electricity,0,{},BE,curtailment,excess |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| name,amount,bus,carrier,profile,region,tech,type | ||
| BB-electricity-demand,20327320000,BB-electricity,electricity,BB-electricity-demand-profile,BB,demand,load | ||
| BE-electricity-demand,13400000000,BE-electricity,electricity,BE-electricity-demand-profile,BE,demand,load |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| name,bus,capacity,capacity_cost,carrier,efficiency,expandable,input_parameters,loss_rate,marginal_cost,output_parameters,region,storage_capacity,storage_capacity_cost,tech,type | ||
| BB-electricity-liion_battery,BB-electricity,0,6.6,electricity,0.87,True,{},0,0,{},BB,0,36.99,liion_battery,storage | ||
| BE-electricity-liion_battery,BE-electricity,0,6.6,electricity,0.87,True,{},0,0,{},BE,0,36.99,liion_battery,storage |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| name,bus,capacity,carrier,marginal_cost,output_parameters,region,tech,type | ||
| BB-electricity-shortage,BB-electricity,,electricity,100000,{},BB,shortage,shortage | ||
| BE-electricity-shortage,BE-electricity,,electricity,100000,{},BE,shortage,shortage |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| name,carrier,from_bus,from_to_capacity,loss,region,tech,to_bus,to_from_capacity,type | ||
| BE-BB-electricity-transmission,electricity,BE-electricity,3000000,0,BE_BB,transmission,BB-electricity,3000000,link |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| name,bus,capacity,capacity_cost,carrier,marginal_cost,output_parameters,profile,region,tech,type | ||
| BB-solar-pv,BB-electricity,11300000,,solar,0,{},BB-solar-pv-profile,BB,pv,volatile | ||
| BE-solar-pv,BE-electricity,400000,,solar,0,{},BE-solar-pv-profile,BE,pv,volatile |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| name,bus,capacity,capacity_cost,carrier,marginal_cost,output_parameters,profile,region,tech,type | ||
| BB-wind-onshore,BB-electricity,9900000,,wind,0,{},BB-wind-onshore-profile,BB,onshore,volatile | ||
| BE-wind-onshore,BE-electricity,0,,wind,0,{},BE-wind-onshore-profile,BE,onshore,volatile |
Uh oh!
There was an error while loading. Please reload this page.