From 7d2287a7534526e5c8eb750185dc3291aa89adb6 Mon Sep 17 00:00:00 2001 From: Eirik Botten Nicolaysen Date: Mon, 12 Oct 2026 10:50:23 +0200 Subject: [PATCH 1/2] fix(data): add biomass, biofuel and waste factors to carbon_intensity_per_source.json A mix carrying biomass or waste had no factor for them, so the two types were left out of the computed sum, the sanity check failed and the world average was returned. Add biomass (230, IPCC AR5 WG3 Annex III median), biofuel (same factor, the name global_energy_mix.json uses) and waste (one value, assumptions in waste_source). Refs #1415 --- .../carbon_intensity_per_source.json | 8 ++- tests/test_emissions.py | 55 ++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/codecarbon/data/private_infra/carbon_intensity_per_source.json b/codecarbon/data/private_infra/carbon_intensity_per_source.json index 8ce6e8b89..239061499 100644 --- a/codecarbon/data/private_infra/carbon_intensity_per_source.json +++ b/codecarbon/data/private_infra/carbon_intensity_per_source.json @@ -19,5 +19,11 @@ "solar": 48, "solar_source": "http://www.world-nuclear.org/uploadedFiles/org/WNA/Publications/Working_Group_Reports/comparison_of_lifecycle.pdf", "wind": 26, - "wind_source": "http://www.world-nuclear.org/uploadedFiles/org/WNA/Publications/Working_Group_Reports/comparison_of_lifecycle.pdf" + "wind_source": "http://www.world-nuclear.org/uploadedFiles/org/WNA/Publications/Working_Group_Reports/comparison_of_lifecycle.pdf", + "biomass": 230, + "biomass_source": "IPCC AR5 WG3 Annex III, Table A.III.2, 'Biomass - dedicated', median lifecycle emissions (min 130, max 420): https://www.ipcc.ch/site/assets/uploads/2018/02/ipcc_wg3_ar5_annex-iii.pdf", + "biofuel": 230, + "biofuel_source": "Same factor as biomass. global_energy_mix.json names bioenergy generation biofuel_TWh, so the factor is reachable under that name.", + "waste": 230, + "waste_source": "One value for mixed renewable and non-renewable waste: the biomass factor, following Electricity Maps, which groups ENTSO-E B17 Waste with biomass (https://github.com/electricitymaps/electricitymaps-contrib/blob/b7469384a7/electricitymap/contrib/parsers/ENTSOE.py#L123). The non-renewable fraction varies by country and year and is not modelled." } \ No newline at end of file diff --git a/tests/test_emissions.py b/tests/test_emissions.py index 3361f2d1d..2e067d306 100644 --- a/tests/test_emissions.py +++ b/tests/test_emissions.py @@ -50,10 +50,63 @@ def test_emissions_CLOUD_GCP(self): def test_get_carbon_intensity_per_source_data(self): # pytest tests/test_emissions.py::TestEmissions::test_get_carbon_intensity_per_source_data carbon_intensity = DataSource().get_carbon_intensity_per_source_data() - self.assertEqual(len(carbon_intensity.keys()), 21) + self.assertEqual(len(carbon_intensity.keys()), 27) self.assertGreater(carbon_intensity["coal"], 800) self.assertLess(carbon_intensity["wind"], 80) + def test_energy_mix_with_biomass_and_waste_is_not_dropped(self): + """ + A mix carrying biomass and waste must be priced from the factor table. + Without a factor for them, the two types are left out of the computed + sum, the sanity check fails and the world average is returned (#1415). + """ + # GIVEN + factors = DataSource().get_carbon_intensity_per_source_data() + energy_mix = { + "total_TWh": 10.0, + "hydroelectricity_TWh": 6.0, + "biomass_TWh": 3.0, + "waste_TWh": 1.0, + } + + # WHEN + rate = Emissions._global_energy_mix_to_emissions_rate(energy_mix) + + # THEN + self.assertNotAlmostEqual( + rate.kgs_per_kWh * 1000, factors["world_average"], places=6 + ) + expected = ( + 6.0 * factors["hydroelectricity"] + + 3.0 * factors["biomass"] + + 1.0 * factors["waste"] + ) / 10.0 + self.assertAlmostEqual(rate.kgs_per_kWh * 1000, expected, places=6) + + def test_energy_mix_with_biofuel_key_from_global_energy_mix(self): + """ + global_energy_mix.json names bioenergy generation ``biofuel_TWh``, so + the factor has to be reachable under that name as well. + """ + # GIVEN + factors = DataSource().get_carbon_intensity_per_source_data() + energy_mix = { + "total_TWh": 10.0, + "hydroelectricity_TWh": 6.0, + "biofuel_TWh": 4.0, + } + + # WHEN + rate = Emissions._global_energy_mix_to_emissions_rate(energy_mix) + + # THEN + self.assertNotAlmostEqual( + rate.kgs_per_kWh * 1000, factors["world_average"], places=6 + ) + expected = (6.0 * factors["hydroelectricity"] + 4.0 * factors["biomass"]) / 10.0 + self.assertEqual(factors["biofuel"], factors["biomass"]) + self.assertAlmostEqual(rate.kgs_per_kWh * 1000, expected, places=6) + def test_get_emissions_PRIVATE_INFRA_FRA(self): """ European country is a specific case as we have there carbon intensity to From 8b0487b901aeb8ea5df58a1e75d983493e148421 Mon Sep 17 00:00:00 2001 From: Eirik Botten Nicolaysen Date: Mon, 12 Oct 2026 11:01:42 +0200 Subject: [PATCH 2/2] docs: add biomass, biofuel and waste factors --- docs/explanation/methodology.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/explanation/methodology.md b/docs/explanation/methodology.md index ec3fbdb7d..ef6a09c1f 100644 --- a/docs/explanation/methodology.md +++ b/docs/explanation/methodology.md @@ -70,10 +70,13 @@ intensity of electricity using this table: | Coal | 995 | | Petroleum | 816 | | Natural Gas | 743 | +| Biofuel | 230 | +| Biomass | 230 | | Geothermal | 38 | | Hydroelectricity | 26 | | Nuclear | 29 | | Solar | 48 | +| Waste | 230 | | Wind | 26 | *Carbon Intensity Across Energy Sources* @@ -82,6 +85,8 @@ Sources: - [for fossil energies](https://github.com/responsibleproblemsolving/energy-usage#conversion-to-co2) - [for renewables energies](http://www.world-nuclear.org/uploadedFiles/org/WNA/Publications/Working_Group_Reports/comparison_of_lifecycle.pdf) +- [for biomass and biofuel](https://www.ipcc.ch/site/assets/uploads/2018/02/ipcc_wg3_ar5_annex-iii.pdf) (IPCC AR5 WG3 Annex III, Table A.III.2, median for "Biomass — dedicated") +- [for waste](https://github.com/electricitymaps/electricitymaps-contrib/blob/b7469384a7/electricitymap/contrib/parsers/ENTSOE.py#L123) (the biomass factor, following Electricity Maps, which groups waste with biomass) Then, for example, if the Energy Mix of the Grid Electricity is 25% Coal, 35% Petroleum, 26% Natural Gas and 14% Nuclear: