SupplyChain class#

[2]:
import numpy as np
import pandas as pd
from climada.hazard import TCTracks, TropCyclone, Centroids
from climada.entity import ImpactFuncSet, ImpfTropCyclone
from climada_petals.engine import SupplyChain

This tutorial shows how to use the SupplyChain class of CLIMADA. This class allows assessing indirect impacts via Input-Output modeling. Before diving into this class, it is highly recommended the user first familiarizes herself with the Exposures, Hazard and Impact classes.

1. Load Multi-Regional Input-Output Tables (MRIOT) data.#

At first, one needs to load Input Output data. SupplyChain has a function to download and read multi-regional input-output tables (MRIOT) from the 2016 release of WIOD project (www.wiod.org). Yearly WIOT tables are available for the period 2000-2014. A table is automatically downloaded the first time it is used.

[3]:
supplychain = SupplyChain()
supplychain.read_wiod16(year=2012)

Let’s now look at what data are now loaded into SupplyChain, i.e. modelled countries, sectors and IO data structure.

[4]:
supplychain.mriot_reg_names
[4]:
array(['AUS', 'AUT', 'BEL', 'BGR', 'BRA', 'CAN', 'CHE', 'CHN', 'CYP',
       'CZE', 'DEU', 'DNK', 'ESP', 'EST', 'FIN', 'FRA', 'GBR', 'GRC',
       'HRV', 'HUN', 'IDN', 'IND', 'IRL', 'ITA', 'JPN', 'KOR', 'LTU',
       'LUX', 'LVA', 'MEX', 'MLT', 'NLD', 'NOR', 'POL', 'PRT', 'ROU',
       'RUS', 'SVK', 'SVN', 'SWE', 'TUR', 'TWN', 'USA', 'ROW'],
      dtype=object)

There are 43 countries plus 1. The additional “country” refers to all countries not explicitly modeled which are aggregated into a Rest of World (ROW) “country”.

[5]:
supplychain.sectors
[5]:
array(['Crop and animal production, hunting and related service activities',
       'Forestry and logging', 'Fishing and aquaculture',
       'Mining and quarrying',
       'Manufacture of food products, beverages and tobacco products',
       'Manufacture of textiles, wearing apparel and leather products',
       'Manufacture of wood and of products of wood and cork, except furniture; manufacture of articles of straw and plaiting materials',
       'Manufacture of paper and paper products',
       'Printing and reproduction of recorded media',
       'Manufacture of coke and refined petroleum products ',
       'Manufacture of chemicals and chemical products ',
       'Manufacture of basic pharmaceutical products and pharmaceutical preparations',
       'Manufacture of rubber and plastic products',
       'Manufacture of other non-metallic mineral products',
       'Manufacture of basic metals',
       'Manufacture of fabricated metal products, except machinery and equipment',
       'Manufacture of computer, electronic and optical products',
       'Manufacture of electrical equipment',
       'Manufacture of machinery and equipment n.e.c.',
       'Manufacture of motor vehicles, trailers and semi-trailers',
       'Manufacture of other transport equipment',
       'Manufacture of furniture; other manufacturing',
       'Repair and installation of machinery and equipment',
       'Electricity, gas, steam and air conditioning supply',
       'Water collection, treatment and supply',
       'Sewerage; waste collection, treatment and disposal activities; materials recovery; remediation activities and other waste management services ',
       'Construction',
       'Wholesale and retail trade and repair of motor vehicles and motorcycles',
       'Wholesale trade, except of motor vehicles and motorcycles',
       'Retail trade, except of motor vehicles and motorcycles',
       'Land transport and transport via pipelines', 'Water transport',
       'Air transport',
       'Warehousing and support activities for transportation',
       'Postal and courier activities',
       'Accommodation and food service activities',
       'Publishing activities',
       'Motion picture, video and television programme production, sound recording and music publishing activities; programming and broadcasting activities',
       'Telecommunications',
       'Computer programming, consultancy and related activities; information service activities',
       'Financial service activities, except insurance and pension funding',
       'Insurance, reinsurance and pension funding, except compulsory social security',
       'Activities auxiliary to financial services and insurance activities',
       'Real estate activities',
       'Legal and accounting activities; activities of head offices; management consultancy activities',
       'Architectural and engineering activities; technical testing and analysis',
       'Scientific research and development',
       'Advertising and market research',
       'Other professional, scientific and technical activities; veterinary activities',
       'Administrative and support service activities',
       'Public administration and defence; compulsory social security',
       'Education', 'Human health and social work activities',
       'Other service activities',
       'Activities of households as employers; undifferentiated goods- and services-producing activities of households for own use',
       'Activities of extraterritorial organizations and bodies'],
      dtype=object)
[6]:
print(supplychain.sectors.shape)
(56,)

There are 56 economic sectors. These sectors can also be grouped into higher-level sectors. For instance, in the aftermath we will model the service sector which will include the following sectors:

[7]:
supplychain.sectors[range(26,56)]
[7]:
array(['Construction',
       'Wholesale and retail trade and repair of motor vehicles and motorcycles',
       'Wholesale trade, except of motor vehicles and motorcycles',
       'Retail trade, except of motor vehicles and motorcycles',
       'Land transport and transport via pipelines', 'Water transport',
       'Air transport',
       'Warehousing and support activities for transportation',
       'Postal and courier activities',
       'Accommodation and food service activities',
       'Publishing activities',
       'Motion picture, video and television programme production, sound recording and music publishing activities; programming and broadcasting activities',
       'Telecommunications',
       'Computer programming, consultancy and related activities; information service activities',
       'Financial service activities, except insurance and pension funding',
       'Insurance, reinsurance and pension funding, except compulsory social security',
       'Activities auxiliary to financial services and insurance activities',
       'Real estate activities',
       'Legal and accounting activities; activities of head offices; management consultancy activities',
       'Architectural and engineering activities; technical testing and analysis',
       'Scientific research and development',
       'Advertising and market research',
       'Other professional, scientific and technical activities; veterinary activities',
       'Administrative and support service activities',
       'Public administration and defence; compulsory social security',
       'Education', 'Human health and social work activities',
       'Other service activities',
       'Activities of households as employers; undifferentiated goods- and services-producing activities of households for own use',
       'Activities of extraterritorial organizations and bodies'],
      dtype=object)

Whether to aggregate sectors into main sectors and how to do it is up to the user, according to the application of interest and data availability. Default settings are available in CLIMADA based on the built-in datasets. These will be introduced below when calculating direct damages.

[8]:
supplychain.mriot_data
[8]:
array([[11105.733356382272, 315.7113177373571, 179.43254266338693, ...,
        9.093853356314124, 0, 1.1873518978687656e-06],
       [116.88308162207898, 139.3046230501366, 0.4165797269551787, ...,
        0.016109951596559337, 0, 2.9150840971500206e-08],
       [22.556627754337466, 0.011392711240065655, 23.191690635397794,
        ..., 0.02463511351049634, 0, 2.9671358991110717e-09],
       ...,
       [2.0888621906340483, 0.06898124909560921, 0.18736619171021462,
        ..., 15914.85428702459, 0, 0.7881946937807305],
       [0.041425098917944464, 4.0179492086967524e-05,
        0.00019545212518185459, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0]], dtype=object)
[9]:
supplychain.mriot_data.shape
[9]:
(2464, 2464)

The MRIO table is a squared matrix with columns (and rows) equal to the number of economic sectors times the number of modeled countries, i.e. 56x44 = 2464. Each column (row) reports input (output) data of all sectors of a given country until all countries are reported. The total production from all subsectors of all countries is:

[10]:
supplychain.total_prod
[10]:
array([71514.7394, 2525.2804, 3080.4692, ..., 409216.80039034015,
       21108.22611227322, 33.03248952629331], dtype=object)
[11]:
print(supplychain.total_prod.shape)
(2464,)

The following dict allows accessing mriot data of single countries:

[12]:
supplychain.reg_pos
[12]:
{'AUS': range(0, 56),
 'AUT': range(56, 112),
 'BEL': range(112, 168),
 'BGR': range(168, 224),
 'BRA': range(224, 280),
 'CAN': range(280, 336),
 'CHE': range(336, 392),
 'CHN': range(392, 448),
 'CYP': range(448, 504),
 'CZE': range(504, 560),
 'DEU': range(560, 616),
 'DNK': range(616, 672),
 'ESP': range(672, 728),
 'EST': range(728, 784),
 'FIN': range(784, 840),
 'FRA': range(840, 896),
 'GBR': range(896, 952),
 'GRC': range(952, 1008),
 'HRV': range(1008, 1064),
 'HUN': range(1064, 1120),
 'IDN': range(1120, 1176),
 'IND': range(1176, 1232),
 'IRL': range(1232, 1288),
 'ITA': range(1288, 1344),
 'JPN': range(1344, 1400),
 'KOR': range(1400, 1456),
 'LTU': range(1456, 1512),
 'LUX': range(1512, 1568),
 'LVA': range(1568, 1624),
 'MEX': range(1624, 1680),
 'MLT': range(1680, 1736),
 'NLD': range(1736, 1792),
 'NOR': range(1792, 1848),
 'POL': range(1848, 1904),
 'PRT': range(1904, 1960),
 'ROU': range(1960, 2016),
 'RUS': range(2016, 2072),
 'SVK': range(2072, 2128),
 'SVN': range(2128, 2184),
 'SWE': range(2184, 2240),
 'TUR': range(2240, 2296),
 'TWN': range(2296, 2352),
 'USA': range(2352, 2408),
 'ROW': range(2408, 2464)}

For example, focusing on Switzerland, to find output data from all swiss sectors one can do:

[13]:
supplychain.mriot_data[supplychain.reg_pos['CHE']]
[13]:
array([[0.16796253031842162, 0.004777144111849153, 0.002736270353709005,
        ..., 0.12834852430129112, 0, 1.6758007628524304e-08],
       [8.51026746906875e-05, 7.127402684742127e-05,
        1.9350907062673556e-06, ..., 0.0007570977491247835, 0,
        1.3699629047508064e-09],
       [4.7138344808091295e-05, 9.671160838557614e-09,
        6.697562625578982e-05, ..., 0.0009232593169242273, 0,
        1.1120045630264473e-10],
       ...,
       [0.008508978608710327, 3.1972146323171236e-05,
        0.00046072292226048554, ..., 0.029862336991154915, 0,
        1.4789538839516966e-06],
       [9.500104969801383e-07, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0]], dtype=object)

Similarly, one can find the total production of all Swiss sectors:

[14]:
supplychain.total_prod[supplychain.reg_pos['CHE']]
[14]:
array([10884.279940160777, 674.088481002245, 41.224100570050936,
       2054.5309263989934, 39841.6239844894, 3648.168376381703,
       8480.201098809475, 3688.826352338922, 4255.674165800708,
       3501.317455453859, 18363.278595872554, 78379.69147195964,
       8150.894879859878, 7447.266269845102, 5718.605069058962,
       20135.29803849402, 66467.12373541784, 22646.288496050656,
       31162.492702290187, 2178.324505028241, 5869.153355999175,
       10800.277292026229, 4680.307868675113, 48856.01258517912,
       5780.830493280612, 0, 77613.75291956161, 14161.940349695808,
       125376.47352416613, 42389.765628680085, 41523.925997007325,
       1039.0976694128697, 13234.059687011602, 17225.389030894996,
       8050.766299432082, 24044.706531639047, 10080.003387207098, 0,
       17138.91756562977, 27213.104595857796, 63105.9204496511,
       45928.766683415735, 0, 65051.40098246406, 60745.78454637557, 0,
       19266.754769461568, 0, 9057.661417570102, 31139.843888469703,
       63363.23886998102, 41714.31400559072, 69213.80028365219,
       24057.595454974882, 2126.7054909496537, 0], dtype=object)

2. Define Hazard, Exposure and Vulnerability#

Let’s now define hazard, exposure and vulnerability. This is handled via the related CLIMADA classes. In this tutorial we use LitPop for exposure and TropCyclone for hazard which we load from the CLIMADA Data API.

[3]:
from climada.util.api_client import Client
client = Client()

We will focus on the impact of tropical cyclones affecting the Philippines, Taiwan, Vietnam and Japan in 2012 and 2013. Japan and Taiwan are modeled explicitly by the MRIO table, while the Philippines and Vietnam are modeled as Rest of World, they are thus aggregated into a single country.

[21]:
from climada.entity import Exposures

countries = ['PHL', 'TWN', 'VNM', 'JPN']
exp_lp = Exposures.concat([client.get_litpop_default(country) for country in countries])
2022-05-18 14:27:23,357 - climada.entity.exposures.base - INFO - Reading /Users/szelie/climada/data/exposures/litpop/LitPop_150arcsec_PHL/v1/LitPop_150arcsec_PHL.hdf5
2022-05-18 14:27:24,713 - climada.entity.exposures.base - INFO - Reading /Users/szelie/climada/data/exposures/litpop/LitPop_150arcsec_TWN/v1/LitPop_150arcsec_TWN.hdf5
2022-05-18 14:27:25,865 - climada.entity.exposures.base - INFO - Reading /Users/szelie/climada/data/exposures/litpop/LitPop_150arcsec_VNM/v1/LitPop_150arcsec_VNM.hdf5
2022-05-18 14:27:27,333 - climada.entity.exposures.base - INFO - Reading /Users/szelie/climada/data/exposures/litpop/LitPop_150arcsec_JPN/v1/LitPop_150arcsec_JPN.hdf5
[22]:
exp_lp.plot_hexbin(pop_name=False);
/Users/szelie/miniconda3/envs/climada_env/lib/python3.8/site-packages/pyproj/crs/crs.py:1256: UserWarning: You will likely lose important projection information when converting to a PROJ string from another format. See: https://proj.org/faq.html#what-is-the-best-format-for-describing-coordinate-reference-systems
  return self._crs.to_proj4(version=version)
../_images/tutorial_climada_engine_SupplyChain_30_1.png
[ ]:
tc_tracks=TCTracks.from_ibtracs_netcdf(year_range=(2012,2013), basin='WP')
[ ]:
tc_tracks.plot();
[ ]:
centr = Centroids.from_lat_lon(exp_lp.gdf.latitude.values, exp_lp.gdf.longitude.values)
[ ]:
tc_cyclone = TropCyclone.from_tracks(tracks=tc_tracks, centroids=centr)
[26]:
from climada.hazard import Hazard
tc_cyclone = Hazard.concat([client.get_hazard('tropical_cyclone', properties={'country_iso3alpha':country,'climate_scenario':'historical','nb_synth_tracks':'10'}) for country in countries])
2022-05-18 14:33:09,702 - climada.hazard.base - INFO - Reading /Users/szelie/climada/data/hazard/tropical_cyclone/tropical_cyclone_10synth_tracks_150arcsec_PHL_1980_2020/v1/tropical_cyclone_10synth_tracks_150arcsec_PHL_1980_2020.hdf5
2022-05-18 14:33:14,001 - climada.hazard.base - INFO - Reading /Users/szelie/climada/data/hazard/tropical_cyclone/tropical_cyclone_10synth_tracks_150arcsec_TWN_1980_2020/v1/tropical_cyclone_10synth_tracks_150arcsec_TWN_1980_2020.hdf5
2022-05-18 14:33:18,387 - climada.hazard.base - INFO - Reading /Users/szelie/climada/data/hazard/tropical_cyclone/tropical_cyclone_10synth_tracks_150arcsec_VNM_1980_2020/v1/tropical_cyclone_10synth_tracks_150arcsec_VNM_1980_2020.hdf5
2022-05-18 14:33:22,799 - climada.hazard.base - INFO - Reading /Users/szelie/climada/data/hazard/tropical_cyclone/tropical_cyclone_10synth_tracks_150arcsec_JPN_1980_2020/v1/tropical_cyclone_10synth_tracks_150arcsec_JPN_1980_2020.hdf5
2022-05-18 14:33:23,059 - climada.util.coordinates - INFO - No exact centroid match found. Reprojecting coordinates to nearest neighbor closer than the threshold = 0
2022-05-18 14:33:23,074 - climada.util.coordinates - INFO - No exact centroid match found. Reprojecting coordinates to nearest neighbor closer than the threshold = 0
2022-05-18 14:33:23,087 - climada.util.coordinates - INFO - No exact centroid match found. Reprojecting coordinates to nearest neighbor closer than the threshold = 0
2022-05-18 14:33:23,105 - climada.util.coordinates - INFO - No exact centroid match found. Reprojecting coordinates to nearest neighbor closer than the threshold = 0
[27]:
tc_cyclone.plot_intensity(event=0);
/Users/szelie/miniconda3/envs/climada_env/lib/python3.8/site-packages/pyproj/crs/crs.py:1256: UserWarning: You will likely lose important projection information when converting to a PROJ string from another format. See: https://proj.org/faq.html#what-is-the-best-format-for-describing-coordinate-reference-systems
  return self._crs.to_proj4(version=version)
../_images/tutorial_climada_engine_SupplyChain_36_1.png
[28]:
impf_tc = ImpfTropCyclone.from_emanuel_usa()

# add the impact function to an Impact function set
impf_set = ImpactFuncSet()
impf_set.append(impf_tc)
impf_set.check()
2022-05-18 14:33:50,697 - climada.entity.impact_funcs.base - WARNING - For intensity = 0, mdd != 0 or paa != 0. Consider shifting the origin of the intensity scale. In impact.calc the impact is always null at intensity = 0.
[29]:
[haz_type] = impf_set.get_hazard_types()
[haz_id] = impf_set.get_ids()[haz_type]

# Exposures: rename column and assign id
exp_lp.gdf.rename(columns={"impf_": "impf_" + haz_type}, inplace=True)
exp_lp.gdf['impf_' + haz_type] = haz_id
exp_lp.check()
2022-05-18 14:33:59,389 - climada.entity.exposures.base - INFO - category_id not set.
2022-05-18 14:33:59,390 - climada.entity.exposures.base - INFO - cover not set.
2022-05-18 14:33:59,391 - climada.entity.exposures.base - INFO - deductible not set.
2022-05-18 14:33:59,392 - climada.entity.exposures.base - INFO - centr_ not set.

3. Calculate direct, indirect and total impact per sector and country#

Let’s now calculate direct, indirect and total impacts. For the direct impact, SupplyChain requires as inputs Hazard, Exposures and ImpactFuncSet. In addition, one may want to specify selected_subsec, which allows the user to either define her own aggregation of sectors by providing a list with the positions of the sectors to aggregate or to use built-in sectors aggregations passing a string being either service, manufacturing, agriculture or mining.

For this tutorial, we will model the service sector, as this sector’s exposure can reasonably be modelled via nightlights and population data, i.e. via LitPop.

3.1 Direct impact#

[30]:
supplychain.calc_sector_direct_impact(tc_cyclone, exp_lp, impf_set, selected_subsec='service')
2022-05-18 14:34:04,517 - climada.entity.exposures.base - INFO - category_id not set.
2022-05-18 14:34:04,518 - climada.entity.exposures.base - INFO - cover not set.
2022-05-18 14:34:04,518 - climada.entity.exposures.base - INFO - deductible not set.
2022-05-18 14:34:04,518 - climada.entity.exposures.base - INFO - centr_ not set.
2022-05-18 14:34:04,520 - climada.entity.exposures.base - INFO - Matching 14008 exposures with 52092 centroids.
2022-05-18 14:34:04,521 - climada.util.coordinates - INFO - No exact centroid match found. Reprojecting coordinates to nearest neighbor closer than the threshold = 100
2022-05-18 14:34:04,559 - climada.util.coordinates - WARNING - Distance to closest centroid is greater than 100km for 61 coordinates.
2022-05-18 14:34:04,565 - climada.engine.impact - INFO - Calculating damage for 13944 assets (>0) and 171116 events.
2022-05-18 14:34:05,077 - climada.entity.exposures.base - INFO - category_id not set.
2022-05-18 14:34:05,078 - climada.entity.exposures.base - INFO - cover not set.
2022-05-18 14:34:05,078 - climada.entity.exposures.base - INFO - deductible not set.
2022-05-18 14:34:05,078 - climada.entity.exposures.base - INFO - centr_ not set.
2022-05-18 14:34:05,079 - climada.entity.exposures.base - INFO - Matching 1852 exposures with 52092 centroids.
2022-05-18 14:34:05,080 - climada.util.coordinates - INFO - No exact centroid match found. Reprojecting coordinates to nearest neighbor closer than the threshold = 100
2022-05-18 14:34:05,104 - climada.engine.impact - INFO - Calculating damage for 1850 assets (>0) and 171116 events.
2022-05-18 14:34:05,299 - climada.entity.exposures.base - INFO - category_id not set.
2022-05-18 14:34:05,300 - climada.entity.exposures.base - INFO - cover not set.
2022-05-18 14:34:05,300 - climada.entity.exposures.base - INFO - deductible not set.
2022-05-18 14:34:05,300 - climada.entity.exposures.base - INFO - centr_ not set.
2022-05-18 14:34:05,301 - climada.entity.exposures.base - INFO - Matching 16092 exposures with 52092 centroids.
2022-05-18 14:34:05,302 - climada.util.coordinates - INFO - No exact centroid match found. Reprojecting coordinates to nearest neighbor closer than the threshold = 100
2022-05-18 14:34:05,338 - climada.engine.impact - INFO - Calculating damage for 16092 assets (>0) and 171116 events.
2022-05-18 14:34:05,580 - climada.entity.exposures.base - INFO - category_id not set.
2022-05-18 14:34:05,580 - climada.entity.exposures.base - INFO - cover not set.
2022-05-18 14:34:05,580 - climada.entity.exposures.base - INFO - deductible not set.
2022-05-18 14:34:05,581 - climada.entity.exposures.base - INFO - centr_ not set.
2022-05-18 14:34:05,582 - climada.entity.exposures.base - INFO - Matching 21999 exposures with 52092 centroids.
2022-05-18 14:34:05,583 - climada.util.coordinates - INFO - No exact centroid match found. Reprojecting coordinates to nearest neighbor closer than the threshold = 100
2022-05-18 14:34:05,630 - climada.util.coordinates - WARNING - Distance to closest centroid is greater than 100km for 155 coordinates.
2022-05-18 14:34:05,633 - climada.engine.impact - INFO - Calculating damage for 21839 assets (>0) and 171116 events.

Let’s see what new attributes the class has got now.

[31]:
supplychain.direct_impact
[31]:
array([[    0.        ,     0.        ,     0.        , ...,
        23087.9543457 ,  1350.54381561,     0.        ],
       [    0.        ,     0.        ,     0.        , ...,
        22127.11016846,  1294.33857918,     0.        ],
       [    0.        ,     0.        ,     0.        , ...,
         6108.82322693,   357.33929634,     0.        ],
       ...,
       [    0.        ,     0.        ,     0.        , ...,
        28564.30769587,  1670.88644018,     0.        ],
       [    0.        ,     0.        ,     0.        , ...,
        10012.92150116,   585.71188295,     0.        ],
       [    0.        ,     0.        ,     0.        , ...,
         8393.34371948,   490.97368622,     0.        ]])
[32]:
supplychain.direct_impact.shape
[32]:
(41, 2464)

All impact matrixes (also those below) provide impacts aggregated over years. They have a number of rows equal to the years being modeled (2 years this time, i.e. 2012-2013) and columns equal to the number of countries times the number of sectors. , i.e. 2464 (see also above).

[33]:
supplychain.direct_aai_agg
[33]:
array([    0.        ,     0.        ,     0.        , ...,
       15666.02490373,   916.39352776,     0.        ])
[34]:
supplychain.direct_aai_agg.shape
[34]:
(2464,)

The annual aggregated impact (aai) matrixes provide yearly average impact. They are row vectors with columns equal to the number of countries times the number of sectors, i.e. 2464.

Info for a given country can be accessed as done below:

[35]:
supplychain.direct_aai_agg[supplychain.reg_pos['CHE']]
[35]:
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0.])

with e.g. CHE, we obviously get zeros, as we are modeling direct impacts in east Asia.

[36]:
supplychain.direct_aai_agg[supplychain.reg_pos['JPN']]
[36]:
array([    0.        ,     0.        ,     0.        ,     0.        ,
           0.        ,     0.        ,     0.        ,     0.        ,
           0.        ,     0.        ,     0.        ,     0.        ,
           0.        ,     0.        ,     0.        ,     0.        ,
           0.        ,     0.        ,     0.        ,     0.        ,
           0.        ,     0.        ,     0.        ,     0.        ,
           0.        ,     0.        ,  9838.67109345,  8949.84687991,
       26440.08161889,  6429.20487753, 11459.27526409,  4417.38472357,
        1101.52394681,  4356.60720937,  1567.11646996, 10144.55649288,
        2800.20977783,  4284.5898164 ,  8323.27804044,  8254.91025785,
       23209.17844596,  2392.2124671 ,     0.        ,  3802.13646047,
           0.        ,     0.        ,   952.56944787,  7309.97665108,
       27510.87169815,  5758.44873345,  3362.80894805,   595.6510692 ,
        2609.56072096,  3779.63408214,  4026.81882254,     0.        ])

for e.g. Japan we instead have direct damages. In order to get all positions of countries undergoing direct damages, one can access the following list:

[37]:
supplychain.reg_dir_imp #note we have two ROW for PHL and VNM
[37]:
['ROW', 'TWN', 'ROW', 'JPN']

and do the following:

[38]:
all_pos = [y for cntry in np.unique(supplychain.reg_dir_imp) for y in supplychain.reg_pos[cntry]]
[39]:
print(supplychain.direct_impact.sum(), supplychain.direct_impact[:, all_pos].sum())
26504371.848759018 26504371.848759014
[40]:
print(supplychain.direct_aai_agg.sum(), supplychain.direct_aai_agg[all_pos].sum())
646448.0938721711 646448.0938721711

i.e., the matrix has non-zero values only at positions corresponding to the modelled countries.

3.2 Indirect impact#

For the indirect impact, one can choose the IO modeling approach between Leontief, Ghosh and EEIOA. References are provided below:

[41]:
supplychain.calc_indirect_impact?

Let’s calculate indirect impacts according to the Ghosh method:

[42]:
supplychain.calc_indirect_impact(io_approach='ghosh')
100%|█████████████████| 41/41 [00:54<00:00,  1.33s/it]

The class now has the indirect impact matrix and vector, with structure equal to those introduced for the direct impact:

[43]:
supplychain.indirect_impact
[43]:
array([[7.4129967e+01, 3.3351808e+00, 3.9694197e+00, ..., 1.7156785e+04,
        1.3505438e+03, 8.6859828e-01],
       [6.9721062e+01, 3.1581292e+00, 3.7076104e+00, ..., 1.6379245e+04,
        1.2943386e+03, 8.1573522e-01],
       [2.5946911e+01, 1.1465709e+00, 1.4656199e+00, ..., 4.8063340e+03,
        3.5733929e+02, 2.5262380e-01],
       ...,
       [9.1218567e+01, 4.1233449e+00, 4.8682852e+00, ..., 2.1197357e+04,
        1.6708865e+03, 1.0603704e+00],
       [3.3414661e+01, 1.5074041e+00, 1.7997495e+00, ..., 7.4902305e+03,
        5.8571185e+02, 3.7547651e-01],
       [2.5535261e+01, 1.1609610e+00, 1.3460040e+00, ..., 6.1741611e+03,
        4.9097369e+02, 3.0542269e-01]], dtype=float32)
[44]:
supplychain.indirect_impact.shape
[44]:
(41, 2464)
[45]:
supplychain.indirect_aai_agg
[45]:
array([5.2298084e+01, 2.3510237e+00, 2.8217690e+00, ..., 1.1723578e+04,
       9.1639349e+02, 5.9329712e-01], dtype=float32)

If we now check damages for e.g. Switzerland:

[46]:
supplychain.indirect_aai_agg[supplychain.reg_pos['CHE']]
[46]:
array([6.12235594e+00, 3.36663336e-01, 9.98742506e-03, 1.73659015e+00,
       2.55845985e+01, 3.70811987e+00, 4.22122002e+00, 3.10644650e+00,
       2.95265079e+00, 5.08737135e+00, 2.18594189e+01, 7.76189194e+01,
       6.58413935e+00, 5.79872036e+00, 7.58963156e+00, 1.46589947e+01,
       5.87042923e+01, 2.18801537e+01, 2.19838810e+01, 1.57981372e+00,
       5.01410246e+00, 1.16099319e+01, 3.48509812e+00, 5.96358185e+01,
       5.92795801e+00, 0.00000000e+00, 4.02651863e+01, 7.14907074e+00,
       9.24594803e+01, 1.79876347e+01, 4.73535080e+01, 1.15669584e+00,
       1.95311852e+01, 1.77650127e+01, 7.38797903e+00, 1.34389677e+01,
       9.68868828e+00, 0.00000000e+00, 1.03515415e+01, 4.68948784e+01,
       3.43284149e+01, 3.92883453e+01, 0.00000000e+00, 2.01987476e+01,
       2.34891510e+01, 0.00000000e+00, 1.41462479e+01, 0.00000000e+00,
       9.75877476e+00, 2.01511478e+01, 2.47340012e+01, 9.80667591e+00,
       2.73831367e+01, 1.20131302e+01, 0.00000000e+00, 0.00000000e+00],
      dtype=float32)

there are non-zero values, as CH undergoes indirect impacts due to events happening in east Asia.

We can also visualize coefficients, inverse matrix and risk matrix of the selected IO approach:

[47]:
supplychain.io_data
[47]:
{'coefficients': array([[1.55292928e-01, 4.41463292e-03, 2.50902888e-03, ...,
         1.27160543e-04, 0.00000000e+00, 1.66028979e-11],
        [4.62851897e-02, 5.51640205e-02, 1.64963756e-04, ...,
         6.37947051e-06, 0.00000000e+00, 1.15436055e-11],
        [7.32246507e-03, 3.69836880e-06, 7.52862263e-03, ...,
         7.99719510e-06, 0.00000000e+00, 9.63209113e-13],
        ...,
        [5.10453674e-06, 1.68568960e-07, 4.57865355e-07, ...,
         3.88910100e-02, 0.00000000e+00, 1.92610537e-06],
        [1.96250971e-06, 1.90349914e-09, 9.25952381e-09, ...,
         0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
        [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, ...,
         0.00000000e+00, 0.00000000e+00, 0.00000000e+00]], dtype=float32),
 'inverse': array([[1.1956462e+00, 5.6268987e-03, 3.4478118e-03, ..., 1.8672845e-03,
         0.0000000e+00, 1.3596379e-07],
        [7.2838165e-02, 1.0588253e+00, 7.4798276e-04, ..., 1.1149000e-03,
         0.0000000e+00, 1.1273375e-07],
        [1.4281658e-02, 1.1088801e-04, 1.0078237e+00, ..., 5.9475366e-04,
         0.0000000e+00, 6.5748580e-08],
        ...,
        [9.0543799e-05, 5.0534527e-06, 5.3664330e-06, ..., 1.0438221e+00,
         0.0000000e+00, 2.5101926e-06],
        [4.3887998e-05, 1.0840827e-06, 2.1887270e-06, ..., 5.4405088e-04,
         1.0000000e+00, 4.1392159e-08],
        [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ..., 0.0000000e+00,
         0.0000000e+00, 1.0000000e+00]], dtype=float32),
 'risk_structure': array([[[0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         ...,
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00]],

        [[0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         ...,
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00]],

        [[0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         ...,
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00]],

        ...,

        [[1.0622725e+00, 1.0180643e+00, 2.8106582e-01, ...,
          1.3142385e+00, 4.6069267e-01, 3.8617620e-01],
         [5.9287813e-02, 5.6820452e-02, 1.5686914e-02, ...,
          7.3350601e-02, 2.5712293e-02, 2.1553360e-02],
         [6.2959746e-02, 6.0339566e-02, 1.6658468e-02, ...,
          7.7893496e-02, 2.7304756e-02, 2.2888245e-02],
         ...,
         [1.2246267e+04, 1.1736617e+04, 3.2402297e+03, ...,
          1.5151022e+04, 5.3110337e+03, 4.4519805e+03],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [2.9449932e-02, 2.8224323e-02, 7.7921338e-03, ...,
          3.6435317e-02, 1.2772022e-02, 1.0706163e-02]],

        [[5.9272666e-02, 5.6805927e-02, 1.5682906e-02, ...,
          7.3331863e-02, 2.5705721e-02, 2.1547852e-02],
         [1.4641011e-03, 1.4031701e-03, 3.8738534e-04, ...,
          1.8113790e-03, 6.3496007e-04, 5.3225609e-04],
         [2.9559718e-03, 2.8329538e-03, 7.8211818e-04, ...,
          3.6571142e-03, 1.2819634e-03, 1.0746074e-03],
         ...,
         [7.3476458e-01, 7.0418602e-01, 1.9441076e-01, ...,
          9.0904725e-01, 3.1865707e-01, 2.6711467e-01],
         [1.3505438e+03, 1.2943386e+03, 3.5733929e+02, ...,
          1.6708865e+03, 5.8571185e+02, 4.9097369e+02],
         [5.5901924e-05, 5.3575470e-05, 1.4791045e-05, ...,
          6.9161601e-05, 2.4243880e-05, 2.0322461e-05]],

        [[0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         ...,
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00],
         [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ...,
          0.0000000e+00, 0.0000000e+00, 0.0000000e+00]]], dtype=float32),
 'io_approach': 'ghosh'}

3.3 Total impact#

Finally, let’s calculate total impacts, as the sum of both direct and indirect. Therefore, the impact matrixes have the same structure as the direct and indirect matrixes.

[48]:
supplychain.calc_total_impact()
[49]:
supplychain.total_impact
[49]:
array([[7.41299667e+01, 3.33518076e+00, 3.96941972e+00, ...,
        4.02447395e+04, 2.70108764e+03, 8.68598282e-01],
       [6.97210617e+01, 3.15812922e+00, 3.70761037e+00, ...,
        3.85063553e+04, 2.58867720e+03, 8.15735221e-01],
       [2.59469109e+01, 1.14657092e+00, 1.46561992e+00, ...,
        1.09151572e+04, 7.14678591e+02, 2.52623796e-01],
       ...,
       [9.12185669e+01, 4.12334490e+00, 4.86828518e+00, ...,
        4.97616651e+04, 3.34177291e+03, 1.06037045e+00],
       [3.34146614e+01, 1.50740409e+00, 1.79974949e+00, ...,
        1.75031520e+04, 1.17142374e+03, 3.75476509e-01],
       [2.55352612e+01, 1.16096103e+00, 1.34600401e+00, ...,
        1.45675049e+04, 9.81947380e+02, 3.05422693e-01]])
[50]:
supplychain.total_aai_agg
[50]:
array([5.22980898e+01, 2.35102410e+00, 2.82176930e+00, ...,
       2.73896023e+04, 1.83278705e+03, 5.93297099e-01])

Finally, one can for example visualize total annual average impacts to all Japanese (direct plus indirect) and Swiss (only direct) subsector after TC in East Asia:

[51]:
df_imp = pd.DataFrame(data=np.vstack([supplychain.total_aai_agg[supplychain.reg_pos['CHE']],
                                      supplychain.total_aai_agg[supplychain.reg_pos['JPN']]]),
                      columns=supplychain.sectors,
                      index=['CHE', 'JPN'])
[52]:
df_imp #in M USD
[52]:
Crop and animal production, hunting and related service activities Forestry and logging Fishing and aquaculture Mining and quarrying Manufacture of food products, beverages and tobacco products Manufacture of textiles, wearing apparel and leather products Manufacture of wood and of products of wood and cork, except furniture; manufacture of articles of straw and plaiting materials Manufacture of paper and paper products Printing and reproduction of recorded media Manufacture of coke and refined petroleum products ... Scientific research and development Advertising and market research Other professional, scientific and technical activities; veterinary activities Administrative and support service activities Public administration and defence; compulsory social security Education Human health and social work activities Other service activities Activities of households as employers; undifferentiated goods- and services-producing activities of households for own use Activities of extraterritorial organizations and bodies
CHE 6.122356 0.336663 0.009987 1.736590 25.584600 3.708121 4.221220 3.106446 2.952651 5.087370 ... 14.146247 0.00000 9.758774 20.151147 24.734004 9.806676 27.383137 12.013128 0.000000 0.0
JPN 1025.912033 98.710680 174.078795 504.574508 4522.040574 692.008433 254.184234 1289.234507 666.834182 1060.231072 ... 1931.814146 11785.17252 52156.217260 10713.789611 12304.570882 2367.990215 10929.705709 8919.787116 6088.317831 0.0

2 rows × 56 columns