Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 176 additions & 0 deletions config/direct_emissions_csv.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
schema:
- name: Group
type: node_group
- name: Sector
- name: Subsector
- name: Key
type: node_attribute
value: key
- name: GHG
type: node_attribute
value: "graph.name == :molecules ? inputs.map { |s| s.carrier&.key }.include?(:other_ghg) : false"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a bit 'devvy' to be usable on the long term for modellers. Are there alternatives?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is quite 'devy', @noracato loved it.
If we do not want any code in ETSource then we will implement individual methods for each new special column that needs a calculation or evaluation or odd way to access it. But if the argument is not to require a dev I disagree because you will need to involve a dev to create that exclusive method in the csv exporter anyway.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aaccensi what would be a potential solution to not have this dev-y stuff in the yml, but in the engine method instead? How could the value: then be specified differently?

Copy link
Copy Markdown
Member

@noracato noracato May 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can do a compromise in this case:

# node_api/emissions.rb

def ghg_carrier_key
  inputs.map { |s| s.carrier&.key }.include?(:other_ghg) ? :other_ghg : :co2
end

Like this it becomes a simple node attribute, scoped to the emissions module. Then in ETSource we can do like this:

- name: GHG
  type: node_attribute
  value: ghg_carrier_key

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no complication whatsoever to move this to the parser in the engine, we can simply replace value: and transform: configs by anything sufficiently adequate and explanatory like subtype: ghg that would only do this specific thing we ask it to do.

Perhaps my point did not came across, my point is only about being versatile and create a generic solution that is easily expandable following the very engineering principles we recently defined.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree not to move specific methods in the serialiser as per the engineering principles. How do you feel about my solution to create a scoped method in the NodeApi that can be directly called by the node_attribute type in the serialiser?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I discussed with @noracato the potential options. Preference goes to reducing the complexity in the yml file by moving the method to the NodeApi. @aaccensi would you agree with this solution as well?

transform: "value ? 'Other GHG' : 'CO2'"
- name: CO2_production
label: "CO2 production [kton CO2-eq]"
type: node_attribute
value: direct_reporting_emissions_co2_production
transform: "value * 1e-6"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also feel that we typically solve this type of conversion in a different way, not with an explicit 1e-6 in ETSource. Are there alternatives?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an example of reusing the 'devy' method that you mentioned above, you can use it to do conversion, negations, any kind of mathematical mutation, or print labels based on conditional values, or many other things, it is very versatile by knowing a bit of ruby. Even if we add the dedicated method for the GHG column I think the "transform" method should stay.

Copy link
Copy Markdown
Member

@noracato noracato May 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also feel that we typically solve this type of conversion in a different way

Number conversions you refer to actually happen in ETModel. The emissions methods themselves just return a number float, they have no clue what kind of unit they are returning. So there is no easy way of automatic scaling possible with these results

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed with @noracato that there doesn't seem to be a better way other than putting it like this in the yml. Therefore, I think it's fine to leave it in here like it now is.

- name: CO2_capture
label: "CO2 capture [kton CO2-eq]"
type: node_attribute
value: direct_reporting_emissions_co2_capture
transform: "value * 1e-6"
- name: Other_GHG_emissions
label: "Other GHG emissions [kton CO2-eq]"
type: node_attribute
value: direct_reporting_emissions_other_ghg_emissions
transform: "value * 1e-6"
- name: Total_GHG_emissions
label: "Total GHG emissions[kton CO2-eq]"
type: node_attribute
value: direct_reporting_emissions_total_ghg_emissions
transform: "value * 1e-6"


rows:
- Group: emissions_agriculture_electricity_and_heat_production
Sector: Agriculture
Subsector: Electricity and heat production
- Group: emissions_agriculture_heating
Sector: Agriculture
Subsector: Heating
- Group: emissions_agriculture_non_specified
Sector: Agriculture
Subsector: Non-specified
- Group: emissions_buildings_appliances
Sector: Buildings
Subsector: Appliances
- Group: emissions_buildings_cooling
Sector: Buildings
Subsector: Cooling
- Group: emissions_buildings_non_specified
Sector: Buildings
Subsector: Non-specified
- Group: emissions_buildings_space_heating
Sector: Buildings
Subsector: Space heating
- Group: emissions_energy_ccus
Sector: Energy
Subsector: CCUS
- Group: emissions_energy_electricity_and_heat_production
Sector: Energy
Subsector: Electricity and heat production
- Group: emissions_energy_fuels_production
Sector: Energy
Subsector: Fuels production
- Group: emissions_energy_fugitive_emissions
Sector: Energy
Subsector: Fugitive emissions
- Group: emissions_energy_hydrogen_production
Sector: Energy
Subsector: Hydrogen production
- Group: emissions_energy_methanol_production
Sector: Energy
Subsector: Methanol production
- Group: emissions_energy_steel
Sector: Energy
Subsector: Steel
- Group: emissions_households_cooking
Sector: Households
Subsector: Cooking
- Group: emissions_households_hot_water
Sector: Households
Subsector: Hot water
- Group: emissions_households_non_specified
Sector: Households
Subsector: Non-specified
- Group: emissions_households_space_heating
Sector: Households
Subsector: Space heating
- Group: emissions_industry_aluminium
Sector: Industry
Subsector: Aluminium
- Group: emissions_industry_chemicals
Sector: Industry
Subsector: Chemicals
- Group: emissions_industry_electricity_and_heat_production
Sector: Industry
Subsector: Electricity and heat production
- Group: emissions_industry_fertilizers
Sector: Industry
Subsector: Fertilizers
- Group: emissions_industry_food
Sector: Industry
Subsector: Food
- Group: emissions_industry_non_specified
Sector: Industry
Subsector: Non-specified
- Group: emissions_industry_other
Sector: Industry
Subsector: Other
- Group: emissions_industry_other_metals
Sector: Industry
Subsector: Other metals
- Group: emissions_industry_paper
Sector: Industry
Subsector: Paper
- Group: emissions_industry_refineries
Sector: Industry
Subsector: Refineries
- Group: emissions_industry_steel
Sector: Industry
Subsector: Steel
- Group: emissions_international_transport_international_aviation
Sector: International transport
Subsector: International aviation
- Group: emissions_international_transport_international_navigation
Sector: International transport
Subsector: International navigation
- Group: emissions_lulucf_emissions
Sector: LULUCF
Subsector: Emissions
- Group: emissions_lulucf_removals
Sector: LULUCF
Subsector: Removals
- Group: emissions_national_transport_buses
Sector: National transport
Subsector: Buses
- Group: emissions_national_transport_cars
Sector: National transport
Subsector: Cars
- Group: emissions_national_transport_domestic_aviation
Sector: National transport
Subsector: Domestic aviation
- Group: emissions_national_transport_domestic_navigation
Sector: National transport
Subsector: Domestic navigation
- Group: emissions_national_transport_motorcycles
Sector: National transport
Subsector: Motorcycles
- Group: emissions_national_transport_non_specified
Sector: National transport
Subsector: Non-specified
- Group: emissions_national_transport_trains
Sector: National transport
Subsector: Trains
- Group: emissions_national_transport_trucks
Sector: National transport
Subsector: Trucks
- Group: emissions_national_transport_vans
Sector: National transport
Subsector: Vans
- Group: emissions_other_heating
Sector: Other
Subsector: Heating
- Group: emissions_other_indirect_emissions
Sector: Other
Subsector: Indirect emissions
- Group: emissions_other_non_specified
Sector: Other
Subsector: Non-specified
- Group: emissions_other_other_transportation
Sector: Other
Subsector: Other transportation
- Group: emissions_waste_non_specified
Sector: Waste
Subsector: Non-specified
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
- output.loss = elastic
- output.passenger_kms = 0.17969198877075998
- groups = [
emissions, emissions_national_transport, emissions_national_transport_domestic_aviaton,
emissions, emissions_national_transport, emissions_national_transport_domestic_aviation,
application_group, passenger_transport
]
- free_co2_factor = 0.0
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
- merit_order.level = mv
- merit_order.type = consumer
- groups = [
emissions, emissions_national_transport, emissions_national_transport_domestic_aviaton,
emissions, emissions_national_transport, emissions_national_transport_domestic_aviation,
application_group, passenger_transport, mv_net_demand
]
- free_co2_factor = 0.0
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
- output.loss = elastic
- output.passenger_kms = 0.3051009051128605
- groups = [
emissions, emissions_national_transport, emissions_national_transport_domestic_aviaton,
emissions, emissions_national_transport, emissions_national_transport_domestic_aviation,
application_group, passenger_transport
]
- free_co2_factor = 0.0
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
- output.loss = elastic
- output.passenger_kms = 0.519286631
- groups = [
emissions, emissions_national_transport, emissions_national_transport_domestic_aviaton,
emissions, emissions_national_transport, emissions_national_transport_domestic_aviation,
application_group, passenger_transport
]
- free_co2_factor = 0.0
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
- output.loss = elastic
- output.passenger_kms = 0.2857010428736964
- groups = [
emissions, emissions_national_transport, emissions_national_transport_domestic_aviaton,
emissions, emissions_national_transport, emissions_national_transport_domestic_aviation,
application_group, passenger_transport
]
- free_co2_factor = 0.0