-
Notifications
You must be signed in to change notification settings - Fork 0
/
bi_calibration.py
132 lines (112 loc) · 5.01 KB
/
bi_calibration.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import glob
import logging
import os
from logging import ERROR, getLogger
import shutil
import numpy as np
import pandas as pd
from nccs.analysis import run_pipeline_from_config
from multiprocessing import Pool
getLogger('nccs.analysis').setLevel(ERROR)
def calc_error(file_no_bi, file_bi, weight: float) -> [float, float, float]:
df = pd.read_csv(file_no_bi)
sum_aapl_no_bi = df['AAPL'].sum()
df = pd.read_csv(file_bi)
sum_aapl_bi = df['AAPL'].sum()
return abs(sum_aapl_no_bi * weight - sum_aapl_bi), sum_aapl_no_bi, sum_aapl_bi
def optimize(country, hazard, sectors, n_iterations=20, initial_scale=1, weight=0.47):
lst_cost = np.inf
for i in range(n_iterations):
print(f"Iteration:{i}, Current scale:{initial_scale}")
os.environ['BI_CALIBRATION_SCALE'] = str(round(initial_scale, 6))
# Run the pipeline
config['run_title'] = f'bi-calibration-bi-{country}-{hazard}-{i}'
config['business_interruption'] = True
config['runs'][0]['sectors'] = sectors
config['runs'][0]['hazard'] = hazard
config['runs'][0]['countries'] = [country]
run_pipeline_from_config(config)
file_bi = glob.glob(f'results/{config["run_title"]}/direct/*{sectors[0]}*.csv')[0]
config['run_title'] = f'bi-calibration-no-bi-{country}-{hazard}-{i}'
config['business_interruption'] = False
config['runs'][0]['sectors'] = sectors
config['runs'][0]['hazard'] = hazard
config['runs'][0]['countries'] = [country]
run_pipeline_from_config(config)
file_no_bi = glob.glob(f'results/{config["run_title"]}/direct/*{sectors[0]}*.csv')[0]
cost, no_bi, bi = calc_error(file_no_bi, file_bi, weight)
print(f'Cost: {cost}, no_bi: {no_bi}, bi: {bi}')
if cost < lst_cost:
lst_cost = cost
initial_scale = initial_scale - 0.05
else:
print(f'Cost: {cost}, final scale: {initial_scale}')
return {"cost": cost, "no_bi": no_bi, "bi": bi, "scale": initial_scale}
if __name__ == '__main__':
# Configuration to calibrate against
config = {
"run_title": "bi-calibration-tc",
"n_sim_years": 300, # Number of stochastic years of supply chain impacts to simulate
"io_approach": ["leontief", "ghosh"], # Supply chain IO to use. One or more of "leontief", "ghosh"
"force_recalculation": False, # If an intermediate file or output already exists should it be recalculated?
"use_s3": False, # Also load and save data from an S3 bucket
"log_level": "INFO",
"seed": 161,
# Which parts of the model chain to run:
"do_direct": True, # Calculate direct impacts (that aren't already calculated)
"do_yearsets": True, # Calculate direct impact yearsets (that aren't already calculated)
"do_multihazard": False, # Also combine hazards to create multi-hazard supply chain shocks
"do_indirect": True, # Calculate any indirect supply chain impacts (that aren't already calculated)
# Impact functions:
"business_interruption": True,
# Turn off to assume % asset loss = % production loss. Mostly for debugging and reproducibility
"calibrated": True,
# Turn off to use best guesstimate impact functions. Mostly for debugging and reproducibility
# Parallisation:
"do_parallel": False, # Parallelise some operations
"ncpus": 6,
"runs": [
{
"hazard": "river_flood",
"sectors": [
# "agriculture",
# "forestry", "mining",
"manufacturing",
# "service", "energy", "water",
# "waste"
],
"countries": ['United States'],
"scenario_years": [
{"scenario": "None", "ref_year": "historical"},
# {"scenario": "rcp26", "ref_year": "2060"},
]
}
]
}
#Option 1: all countries
file_path = r"C:\Users\GaudenzHalter\Downloads\bi_scaling.xlsx"
df = pd.read_excel(file_path)
countries = list(zip(df['Countries'], df['bi_scale']))
#Option 2: Reduced country set
countries = [
("United States", 0.31),
("Thailand", 0.29),
]
result = []
for country, weight in countries:
for sector in ["forestry", "mining", "manufacturing", "service", "energy"]:
try:
if sector == "forestry":
inital_weight = 0.9
else:
inital_weight = 0.5
res = optimize(country, "river_flood", [sector], 20, inital_weight, weight)
res['country'] = country
res['sector'] = sector
res['hazard'] = 'river_flood'
os.makedirs('results/calib', exist_ok=True)
pd.DataFrame(res).to_csv(f'results/calib/bi-calibration-{country}-{sector}.csv')
result.append(res)
except Exception as e:
logging.exception(e)
pd.DataFrame(result).to_csv('results/bi-calibration-results_test_without.csv')