vdwow's picture
feat: update to ecologits 0.5.1 + remove own usage to fix it
7f50b6e
from dataclasses import dataclass
from enum import Enum
import pandas as pd
from ecologits.impacts.modeling import Impacts, Energy, GWP, ADPe, PE
from ecologits.tracers.utils import llm_impacts, _avg
from pint import UnitRegistry, Quantity
u = UnitRegistry()
u.define('Wh = watt_hour')
u.define('kWh = kilowatt_hour')
u.define('MWh = megawatt_hour')
u.define('GWh = gigawatt_hour')
u.define('TWh = terawatt_hour')
u.define('gCO2eq = gram')
u.define('kgCO2eq = kilogram')
u.define('tCO2eq = metricton')
u.define('kgSbeq = kilogram')
u.define('kJ = kilojoule')
u.define('MJ = megajoule')
u.define('m = meter')
u.define('km = kilometer')
u.define('s = second')
u.define('min = minute')
u.define('h = hour')
q = u.Quantity
@dataclass
class QImpacts:
energy: Quantity
gwp: Quantity
adpe: Quantity
pe: Quantity
class PhysicalActivity(str, Enum):
RUNNING = "running"
WALKING = "walking"
class EnergyProduction(str, Enum):
NUCLEAR = "nuclear"
WIND = "wind"
COUNTRIES = [
("cook_islands", 38.81, 9_556),
("tonga", 51.15, 104_490),
("comoros", 100, 821_632),
("samoa", 100, 821_632),
]
def df_elec_mix_for_plot():
return pd.DataFrame({
'country': ['Sweden', 'France', 'Canada', 'USA', 'China', 'Australia', 'India'],
'electricity_mix': [46, 81, 238, 679, 1057, 1123, 1583]
})
# From https://www.runningtools.com/energyusage.htm
RUNNING_ENERGY_EQ = q("294 kJ / km") # running 1 km at 10 km/h with a weight of 70 kg
WALKING_ENERGY_EQ = q("196 kJ / km") # walking 1 km at 3 km/h with a weight of 70 kg
# From https://selectra.info/energie/actualites/insolite/consommation-vehicules-electriques-france-2040
# and https://www.tesla.com/fr_fr/support/power-consumption
EV_ENERGY_EQ = q("0.17 kWh / km")
# From https://impactco2.fr/outils/comparateur?value=1&comparisons=streamingvideo
STREAMING_GWP_EQ = q("15.6 h / kgCO2eq")
# From https://ourworldindata.org/population-growth
ONE_PERCENT_WORLD_POPULATION = 80_000_000
DAYS_IN_YEAR = 365
# For a 900 MW nuclear plant -> 500 000 MWh / month
# From https://www.edf.fr/groupe-edf/espaces-dedies/jeunes-enseignants/pour-les-jeunes/lenergie-de-a-a-z/produire-de-lelectricite/le-nucleaire-en-chiffres
YEARLY_NUCLEAR_ENERGY_EQ = q("6 TWh")
# For a 2MW wind turbine
# https://www.ecologie.gouv.fr/eolien-terrestre
YEARLY_WIND_ENERGY_EQ = q("4.2 GWh")
# Ireland yearly electricity consumption
# From https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption
YEARLY_IRELAND_ELECTRICITY_CONSUMPTION = q("33 TWh")
IRELAND_POPULATION_MILLION = 5
# From https://impactco2.fr/outils/comparateur?value=1&comparisons=&equivalent=avion-pny
AIRPLANE_PARIS_NYC_GWP_EQ = q("177000 kgCO2eq")
def format_energy(energy: Energy) -> Quantity:
val = q(energy.value, energy.unit)
if val < q("1 kWh"):
val = val.to("Wh")
return val
def format_gwp(gwp: GWP) -> Quantity:
val = q(gwp.value, gwp.unit)
if val < q("1 kgCO2eq"):
val = val.to("gCO2eq")
return val
def format_adpe(adpe: ADPe) -> Quantity:
return q(adpe.value, adpe.unit)
def format_pe(pe: PE) -> Quantity:
val = q(pe.value, pe.unit)
if val < q("1 MJ"):
val = val.to("kJ")
return val
def format_impacts(impacts: Impacts) -> QImpacts:
try:
impacts.energy.value = (impacts.energy.value.max + impacts.energy.value.min)/2
impacts.gwp.value = (impacts.gwp.value.max + impacts.gwp.value.min)/2
impacts.adpe.value = (impacts.adpe.value.max + impacts.adpe.value.min)/2
impacts.pe.value = (impacts.pe.value.max + impacts.pe.value.min)/2
return QImpacts(
energy=format_energy(impacts.energy),
gwp=format_gwp(impacts.gwp),
adpe=format_adpe(impacts.adpe),
pe=format_pe(impacts.pe)
)
except: #when no range
return QImpacts(
energy=format_energy(impacts.energy),
gwp=format_gwp(impacts.gwp),
adpe=format_adpe(impacts.adpe),
pe=format_pe(impacts.pe)
)
def format_impacts_expert(impacts: Impacts) -> QImpacts:
return QImpacts(
energy=format_energy(impacts.energy),
gwp=format_gwp(impacts.gwp),
adpe=format_adpe(impacts.adpe),
pe=format_pe(impacts.pe)
), impacts.usage, impacts.embodied
def format_energy_eq_physical_activity(energy: Quantity) -> tuple[PhysicalActivity, Quantity]:
energy = energy.to("kJ")
running_eq = energy / RUNNING_ENERGY_EQ
if running_eq > q("1 km"):
return PhysicalActivity.RUNNING, running_eq
walking_eq = energy / WALKING_ENERGY_EQ
if walking_eq < q("1 km"):
walking_eq = walking_eq.to("meter")
return PhysicalActivity.WALKING, walking_eq
def format_energy_eq_electric_vehicle(energy: Quantity) -> Quantity:
energy = energy.to("kWh")
ev_eq = energy / EV_ENERGY_EQ
if ev_eq < q("1 km"):
ev_eq = ev_eq.to("meter")
return ev_eq
def format_gwp_eq_streaming(gwp: Quantity) -> Quantity:
gwp = gwp.to("kgCO2eq")
streaming_eq = gwp * STREAMING_GWP_EQ
if streaming_eq < q("1 h"):
streaming_eq = streaming_eq.to("min")
if streaming_eq < q("1 min"):
streaming_eq = streaming_eq.to("s")
return streaming_eq
def format_energy_eq_electricity_production(energy: Quantity) -> tuple[EnergyProduction, Quantity]:
electricity_eq = energy * ONE_PERCENT_WORLD_POPULATION * DAYS_IN_YEAR
electricity_eq = electricity_eq.to("TWh")
if electricity_eq > YEARLY_NUCLEAR_ENERGY_EQ:
return EnergyProduction.NUCLEAR, electricity_eq / YEARLY_NUCLEAR_ENERGY_EQ
electricity_eq = electricity_eq.to("GWh")
return EnergyProduction.WIND, electricity_eq / YEARLY_WIND_ENERGY_EQ
def format_energy_eq_electricity_consumption_ireland(energy: Quantity) -> Quantity:
electricity_eq = energy * ONE_PERCENT_WORLD_POPULATION * DAYS_IN_YEAR
electricity_eq = electricity_eq.to("TWh")
return electricity_eq / YEARLY_IRELAND_ELECTRICITY_CONSUMPTION
def format_gwp_eq_airplane_paris_nyc(gwp: Quantity) -> Quantity:
gwp_eq = gwp * ONE_PERCENT_WORLD_POPULATION * DAYS_IN_YEAR
gwp_eq = gwp_eq.to("kgCO2eq")
return gwp_eq / AIRPLANE_PARIS_NYC_GWP_EQ