@@ -155,71 +155,8 @@ def get_private_infra_emissions(self, energy: Energy, geo: GeoMetadata) -> float
155155 + " >>> Using CodeCarbon's data."
156156 )
157157
158- # NORDIC EMISSION FACTORS DOCUMENTATION
159- # ==========================================
160- # Static emission factors for Nordic electricity regions.
161- # These values represent the carbon intensity (gCO2eq/kWh) of electricity
162- # production in specific Nordic bidding zones.
163- #
164- # DATA SOURCES:
165- # - Sweden/Norway (SE1-4, NO1-5): 18 gCO2eq/kWh
166- # Based on Nordic grid average (<60 gCO2eq/kWh per ENTSO-E)
167- # Source: https://transparency.entsoe.eu/
168- # Nordic Energy Research: https://www.nordicenergy.org/indicators/
169- #
170- # - Finland (FI): 72 gCO2eq/kWh
171- # Source: Fingrid real-time CO2 emissions estimate
172- # https://www.fingrid.fi/en/electricity-market-information/real-time-co2-emissions-estimate/
173- #
174- # UPDATE PROCEDURE:
175- # To update these values annually:
176- # 1. Check latest data from ENTSO-E Transparency Platform
177- # 2. Check Fingrid for Finnish-specific data
178- # 3. Update codecarbon/data/private_infra/nordic_emissions.json
179- # 4. Values should reflect the most recent annual average
180- #
181-
182- # Check for Nordic regions (SE1-4, NO1-5, FI) and use static emission factors
183- nordic_regions = [
184- "SE1" ,
185- "SE2" ,
186- "SE3" ,
187- "SE4" ,
188- "NO1" ,
189- "NO2" ,
190- "NO3" ,
191- "NO4" ,
192- "NO5" ,
193- "FI" ,
194- ]
195- if geo .region is not None and geo .region .upper () in nordic_regions :
196- try :
197- # Get Nordic energy mix data from cache
198- nordic_data = (
199- self ._data_source .get_nordic_country_energy_mix_data ()
200- )
201- region_data = nordic_data ["data" ].get (geo .region .upper ())
202- if region_data :
203- emission_factor_g = region_data [
204- "emission_factor"
205- ] # gCO2eq/kWh
206- emission_factor_kg = (
207- emission_factor_g / 1000
208- ) # Convert to kgCO2eq/kWh
209- emissions = emission_factor_kg * energy .kWh # kgCO2eq
210- logger .debug (
211- f"Nordic region { geo .region } : Retrieved emissions using static factor "
212- + f"{ emission_factor_g } gCO2eq/kWh: { emissions * 1000 } g CO2eq"
213- )
214- return emissions
215- except Exception as e :
216- logger .warning (
217- f"Error loading Nordic emissions data for { geo .region } : { e } . "
218- + "Falling back to default emission calculation."
219- )
220-
221158 compute_with_regional_data : bool = (geo .region is not None ) and (
222- geo .country_iso_code .upper () in ["USA" , "CAN" ]
159+ geo .country_iso_code .upper () in ["USA" , "CAN" , "SWE" , "NOR" , "FIN" ]
223160 )
224161
225162 if compute_with_regional_data :
@@ -233,16 +170,72 @@ def get_private_infra_emissions(self, energy: Energy, geo: GeoMetadata) -> float
233170 )
234171 return self .get_country_emissions (energy , geo )
235172
173+ def _try_get_nordic_region_emissions (
174+ self , energy : Energy , geo : GeoMetadata
175+ ) -> Optional [float ]:
176+ nordic_regions = {
177+ "SE1" ,
178+ "SE2" ,
179+ "SE3" ,
180+ "SE4" ,
181+ "NO1" ,
182+ "NO2" ,
183+ "NO3" ,
184+ "NO4" ,
185+ "NO5" ,
186+ "FI" ,
187+ }
188+ if geo .region is None :
189+ return None
190+
191+ region_upper = geo .region .upper ()
192+ if region_upper not in nordic_regions :
193+ return None
194+
195+ try :
196+ nordic_data = self ._data_source .get_nordic_country_energy_mix_data ()
197+ region_data = nordic_data ["data" ].get (region_upper )
198+ if region_data :
199+ emission_factor_g = region_data ["emission_factor" ]
200+ emission_factor_kg = emission_factor_g / 1000
201+ emissions = emission_factor_kg * energy .kWh
202+ logger .debug (
203+ f"Nordic region { geo .region } : Retrieved emissions using static factor "
204+ + f"{ emission_factor_g } gCO2eq/kWh: { emissions * 1000 } g CO2eq"
205+ )
206+ return emissions
207+ except Exception as e :
208+ logger .warning (
209+ f"Error loading Nordic emissions data for { geo .region } : { e } . "
210+ + "Falling back to default emission calculation."
211+ )
212+ return None
213+
236214 def get_region_emissions (self , energy : Energy , geo : GeoMetadata ) -> float :
237215 """
238216 Computes emissions for a region on private infra.
239217 Given an quantity of power consumed, use regional data
240218 on emissions per unit power consumed or the mix of energy sources.
241219 https://github.com/responsibleproblemsolving/energy-usage#calculating-co2-emissions
220+
221+ get_private_infra_emissions
222+ ├─ Electricity Maps API (si token)
223+ ├─ get_region_emissions (USA/CAN/SWE/NOR/FIN)
224+ │ └─ _try_get_nordic_region_emissions (pour SWE/NOR/FIN)
225+ │ └─ country_emissions_data (pour USA)
226+ │ └─ country_energy_mix_data (pour CAN)
227+ └─ get_country_emissions (fallback)
228+
242229 :param energy: Mean power consumption of the process (kWh)
243230 :param geo: Country and region metadata.
244231 :return: CO2 emissions in kg
245232 """
233+ # Handle Nordic regions (Sweden, Norway, Finland electricity bidding zones)
234+ nordic_emissions = self ._try_get_nordic_region_emissions (energy , geo )
235+ if nordic_emissions is not None :
236+ return nordic_emissions
237+
238+ # Handle USA and Canada regional data
246239 try :
247240 country_emissions_data = self ._data_source .get_country_emissions_data (
248241 geo .country_iso_code .lower ()
0 commit comments