Carbon Emission Calculation#

import pandas as pd

The purpose of this calculation is to determine the appropriate total emission constraints based on the defined scope of the model. The objective is to establish the relationship between this target and the total emissions from the year 1990.

The countries included in the analysis are:

  • AT: Austria

  • BE: Belgium

  • CH: Switzerland

  • CZ: Czech Republic

  • DE: Germany

  • DK: Denmark

  • FR: France

  • IT: Italy

  • LU: Luxembourg

  • NL: Netherlands

  • PL: Poland

  • SE: Sweden

The sector scope for this analysis includes:

  • Power Sector

  • Transport Sector (fossil fuel emissions are excluded)

  • Heating Sector

Since the emissions of individual countries are being compared for the years 1990 and 2005, we first need to extract the emissions data for those years.

1. Extract the total emissions data for the years 1990 and 2005.#

ctrys = ['AT', 'BE', 'CH', 'CZ', 'DE', 'DK', 'FR', 'IT', 'LU', 'NL', 'PL', 'SE']

# 1990 emissions in MtCO2
co2_totals = pd.read_csv("../data/co2_totals_1990.csv", index_col=0).loc[ctrys]

# 2005 emissions in MtCO2
co2_totals_2005 = pd.read_csv("../data/co2_totals_2005.csv", index_col=0).loc[ctrys]

2. Calculate the linearly interpolated targets for 2035.#

Below are the emission reduction targets for each of these countries:

Table 1: Country Specific Emission Reduction Targets

Country

2030

2035

2040

2045

2050

Source

DE

65% below 1990 excl. LULUCF

-

85% below 1990 excl. LULUCF

100%

-

Source

AT

48% below 2005 excl. LULUCF

-

100%

-

-

Source1 Source2

BE

55% below 1990 excl. LULUCF

-

-

-

100%

Source

CH

50% below 1990 excl. LULUCF

-

-

-

100%

Source

CZ

26% below 2005 excl. LULUCF

-

-

-

100%

Source

DK

70% below 1990 incl. LULUCF and 50% below 2005 excl. LULUCF

-

-

100%

110%

Source

FR

47.5% below 2005 excl. LULUCF

-

-

-

100%

Source

IT

43.7% below 2005 excl. LULUCF

-

-

-

100%

Source1 Source2

LU

55% below 2005 excl. LULUCF

-

-

-

100%

Source

NL

55% below 1990

-

-

-

100%

Source

PL

17.7% below 2005 excl. LULUCF

-

-

-

Source

SE

63% below 1990

-

75% below 1990

100%

Source

Since Table 1 do not include the year 2035, we will interpolate the targets linearly to estimate the 2035 values.

Note: Polands 2035 target is deduced based on the EUs Effort Sharing Regulation (ESR) distrubution key in relation to the German interpolated target (source).

# EU Effort Sharing Regulation
esr_targets = {
    "AT": 0.48,
    "BE": 0.47,
    "CZ": 0.26,
    "DE": 0.5,
    "DK": 0.5,
    "FR": 0.475,
    "IT": 0.437,
    "LU": 0.5,
    "NL": 0.48,
    "PL": 0.177,
    "SE": 0.5,
}

# Emission reduction targets for countries with a base year of 1990
target2035_base1990 = dict(DE = 0.75,
                           BE = 0.55 + (1-0.55)*(2035-2030)/(2050-2030),
                           CH = 0.625,
                           DK = 0.7 + (1-0.7)*(2035-2030)/(2045-2030),
                           NL = 0.55 + (1-0.55)*(2035-2030)/(2050-2030),
                           SE = 0.69,
                           PL = (esr_targets["PL"]/esr_targets["DE"])*0.75
                          )

# Emission reduction targets for countries with a base year of 2005
target2035_base2005 = dict(AT = 0.74,
                           CZ = 0.26 + (1-0.26)*(2035-2030)/(2050-2030),
                           FR = 0.475 + (1-0.475)*(2035-2030)/(2050-2030),
                           IT = 0.437 + (1-0.437)*(2035-2030)/(2050-2030),
                           LU = 0.55 + (1-0.55)*(2035-2030)/(2050-2030)
                          )

target_2035 = pd.DataFrame(index=co2_totals.index)
target_2035["base1990"] = target2035_base1990
target_2035["base2005"] = target2035_base2005
target_2035
base1990 base2005
Country_code
AT NaN 0.74000
BE 0.6625 NaN
CH 0.6250 NaN
CZ NaN 0.44500
DE 0.7500 NaN
DK 0.8000 NaN
FR NaN 0.60625
IT NaN 0.57775
LU NaN 0.66250
NL 0.6625 NaN
PL 0.2655 NaN
SE 0.6900 NaN

3. Extract the data and exclude LULUCF from the calculation.#

LULUFC: Land Use, Land Use Change and Forestry

LULUCF is excluded for all the countries listed in Table 1.

# Total emissions incl. LULUCF
co2_totals_incl_lulucf = co2_totals.sum(axis=1)
# Total emissions incl. LULUCF 2005
co2_totals_incl_lulucf_2005 = co2_totals_2005.sum(axis=1)
# Total emissions excl. LULUCF
co2_totals_excl_lulucf = co2_totals.drop(["LULUCF"], axis=1).sum(axis=1)
# Total emissions excl. LULUCF
co2_totals_excl_lulucf_2005 = co2_totals_2005.drop(["LULUCF"], axis=1).sum(axis=1)

pd.DataFrame({"1990":co2_totals_incl_lulucf, "2005":co2_totals_incl_lulucf_2005, "1990 excl. LULUFC":co2_totals_excl_lulucf, "2005 excl. LULUFC":co2_totals_excl_lulucf_2005})
1990 2005 1990 excl. LULUFC 2005 excl. LULUFC
Country_code
AT 49.968104 68.414161 62.124701 79.192432
BE 117.060288 124.024742 120.309343 125.661688
CH 42.515838 43.712103 44.534441 45.915746
CZ 160.298010 119.316791 166.068823 126.738399
DE 1021.884333 851.168952 1052.348544 866.388549
DK 60.858777 57.805099 54.685986 52.164863
FR 374.572263 377.355895 400.777042 426.412463
IT 432.346810 463.962937 438.008802 500.005676
LU 11.927560 11.462305 11.847635 12.105448
NL 169.786966 183.428661 163.302301 177.897237
PL 343.554029 271.748435 376.546518 323.161267
SE 21.112932 19.936933 57.348825 53.852857

4. Calculate the absolute emissions#

This is done by multiplying the remaining emissions (1 - target emissions) by the CO2 emissions for the respective year.

# Calculate aggregated 1990 emissions in MtCO2
co2_1990_aggregated = co2_totals_excl_lulucf.sum()

# Calculate absolute target emissions in 2035 based on shares
target_2035["absolute_emissions"] = ((1-target_2035.base1990) * co2_totals_excl_lulucf).combine_first((1-target_2035.base2005) * co2_totals_excl_lulucf_2005)
target_2035_aggregated = target_2035.absolute_emissions.sum()

display(target_2035)

# Calculate share of 1990 emissions
round(target_2035_aggregated/co2_1990_aggregated,3)
base1990 base2005 absolute_emissions
Country_code
AT NaN 0.74000 20.590032
BE 0.6625 NaN 40.604403
CH 0.6250 NaN 16.700415
CZ NaN 0.44500 70.339812
DE 0.7500 NaN 263.087136
DK 0.8000 NaN 10.937197
FR NaN 0.60625 167.899907
IT NaN 0.57775 211.127397
LU NaN 0.66250 4.085589
NL 0.6625 NaN 55.114527
PL 0.2655 NaN 276.573417
SE 0.6900 NaN 17.778136
0.392

Note: 39.2% (0.392) compared to 1990 emissions is the result when all sectors are included.

Since not all sector is included in the model, we need to divide the remaining emissions further based on the share of remaining emissions in each sector.

5. Extract the emission target by sector and interpolate to the year 2035#

Data is from Europe’s 2040 climate target (Source).

target_sector = pd.read_csv("../data/co2_total_sector.csv", index_col=0)

# calculate linearly interpolated 2035 targets
target_sector['2035 S2'] = (target_sector['2030'] + target_sector['2040 S2'])/2
target_sector_share = target_sector/target_sector.loc['Total Gross GHG Emissions',:]
target_sector
2005 2015 2030 2040 S1 2040 S2 2040 S3 2040 LIFE 2050 S1 2050 S2 2050 S3 2050 LIFE 2035 S2
MtC02-eq
Total Gross GHG Emissions 4641 3914 2301 1273 943 748 740 416 413 411 360.00 1622.0
Power and district heating 1300 1012 339 123 42 23 34 21 22 19 15.00 190.5
Other Energy sectors* 277 237 133 71 59 53 57 39 39 38 36.00 96.0
Industry (Energy) 469 360 232 126 94 75 86 6 6 9 11.00 163.0
Domestic Transport 822 772 583 190 143 120 134 10 8 7 9.00 363.0
Residential and Services** 648 514 221 119 92 75 92 20 19 19 29.00 156.5
Industry (Non-Energy) 343 233 157 139 88 14 13 7 7 7 7.00 122.5
Other Non-Energv sectors*** 101 130 56 33 26 25 25 23 22 22 22.00 41.0
Intra-EU aviation 35 38 43 31 29 28 14 14 12 11 10.00 36.0
Intra-EU navigation 31 27 25 7 6 4 0 0 0 0 0.00 15.5
50% extra-EU maritime MRV 50 42 44 14 11 9 0 0 0 0 0.00 27.5
Agriculture**** 390 385 361 351 302 271 209 249 249 249 194.00 331.5
Waste 155 118 87 68 55 55 55 32 32 32 0.32 71.0
C02 calibration 15 43 24 3 -1 -1 -1 0 0 0 0.00 11.5
Non-C02 calibration 5 2 -3 -3 -3 -3 -3 -3 -3 -3 -3.00 -3.0

6. Select the included sector in the model#

In this list, we only model:

  • Power and district heating

  • Other Energy sectors*

  • Residential and Services**

Note:

  • Other Energy sectors includes emissions from the energy branch as well as other non-CO2 emissions from the energy sector.

  • The Residential and Services sector may include fossil fuel combustion from the agriculture, fishery, and forestry sectors.

include_sector = ['Power and district heating','Residential and Services**','Other Energy sectors*']

target_sector_share_2035 = target_sector_share.loc[include_sector,'2035 S2'].sum()
target_sector_share_2035
0.27311960542540076

Note: 27.3% (0.273) of the emissions come from the included sector, relative to the total emissions from all sectors.

7. Calculate the absolute emission of the included sector emission#

target_2035['included_sector_emissions'] = target_2035['absolute_emissions'] * target_sector_share_2035
display(target_2035)

# Calculate share of 1990 emissions
round(target_2035['included_sector_emissions'].sum()/co2_1990_aggregated,3)
base1990 base2005 absolute_emissions included_sector_emissions
Country_code
AT NaN 0.74000 20.590032 5.623541
BE 0.6625 NaN 40.604403 11.089859
CH 0.6250 NaN 16.700415 4.561211
CZ NaN 0.44500 70.339812 19.211182
DE 0.7500 NaN 263.087136 71.854255
DK 0.8000 NaN 10.937197 2.987163
FR NaN 0.60625 167.899907 45.856756
IT NaN 0.57775 211.127397 57.663031
LU NaN 0.66250 4.085589 1.115854
NL 0.6625 NaN 55.114527 15.052858
PL 0.2655 NaN 276.573417 75.537623
SE 0.6900 NaN 17.778136 4.855557
0.107

10.7% (0.107) compared to 1990 emissions is the answer for the co2_budget for the year 2035