<<

NAME

ProductOpener::EnvironmentalScore - compute the EnvironmentalScore environmental grade of a food product

SYNOPSIS

ProductOpener::EnvironmentalScore is used to compute the EnvironmentalScore environmental grade of a food product.

DESCRIPTION

The modules implements the Environmental-Score computation as defined by a collective that Open Food Facts is part of.

It is based on the French AgriBalyse V3 database that contains environmental impact values for 2500 food product categories.

AgriBalyse provides Life Cycle Analysis (LCA) values for food products categories, and some adjustments to the score are made for actual specific products using data about labels, origins of ingredients, packagings etc.

VARIABLES

%environmental_score_countries_enabled

List of countries for which we are going to compute and display the Environmental-Score.

The list is different from %environmental_score_countries that can contain more countries for which we have some data to compute the Environmental-Score (e.g. distances).

2021-10-28: we will now enable Environmental-Score for all available countries, so this list will be overrode when we load the Environmental-Score data.

FUNCTIONS

load_agribalyse_data()

Loads the AgriBalyse database.

load_environmental_score_data_origins_of_ingredients_distances ( $product_ref )

Loads the transport score matrix used to compute the Environmental-Score "transport" bonus (see https://docs.score-environnemental.com/methodologie/produit/transport).

Despite its name, distances.csv does not hold raw distances but the pre-computed transport scores (/100) from the methodology: each score reflects the CO2 impact of shipping goods from an origin country to a destination country, derived from the distance, the modal mix (road / rail / sea) and ADEME Base Carbone emission factors. France scores 100 (local sourcing) and distant origins score 0. See https://wiki.openfoodfacts.org/Eco-score_transport_-_en for how it was built.

The file is a matrix: rows = origin countries (columns 0..2 = ISO code, EN name, FR name), columns 3+ = destination country codes (the countries where the Eco-score is enabled, e.g. fr, be, de, uk ...). "gb" is normalised to "uk".

Populates the global %environmental_score_data{origins} hash:

    $environmental_score_data{origins}{$origin_id}{
        name_en                    => "...",
        name_fr                    => "...",
        transportation_score_$cc   => <score /100>,   # one per destination country $cc
        transportation_score_world => 0,              # "world" = unspecified destination => no bonus
    }

Also builds %environmental_score_countries (the set of destination countries) and aliases en:unknown / en:world / en:european-union-and-non-european-union to a 0-score origin (unknown origin => no transport bonus).

load_environmental_score_data_origins_of_ingredients( $product_ref )

Loads, for each origin country, the two per-origin components of the Environmental-Score "origins of ingredients" adjustment:

- epi_score: Environmental Performance Index of the country (a separate bonus/malus reflecting the country's environmental policy). - transportation_score_fr: the transport score (/100) for France as defined in the original French Environmental-Score specification.

It first calls load_environmental_score_data_origins_of_ingredients_distances() to load the full transport-score matrix for all destination countries, then reads fr_countries.csv (column 1 = EPI score, column 2 = transport score for France). The France value from fr_countries.csv OVERRIDES the recomputed value from distances.csv, because the distances.csv scores were recomputed in a slightly different way and differ slightly from the original specification.

Resulting structure per origin:

    $environmental_score_data{origins}{$origin_id}{
        epi_score                => <EPI>,
        transportation_score_$cc => <score /100>,   # from distances.csv (all countries)
        transportation_score_fr  => <score /100>,   # overridden from fr_countries.csv
    }

Origins are matched against the taxonomy; special normalisation handles entries like "Congo [DRC]" vs "Congo [Republic]", "Macedonia [FYROM]" and leading articles ("La Guyane" ...). en:unknown / en:world / en:unspecified / en:european-union-and-non-european-union are aliased to a 0-score origin.

At compute time the per-origin score is weighted by the ingredient percentage (score = Σ a_i * p_i) and turned into a bonus of up to 15 points (bonus = x * 0.15, i.e. the /100 weighted score divided by 6.66).

load_environmental_score_data_packaging( $product_ref )

Loads the packaging data needed to compute the Environmental-Score packaging adjustment (a malus): a score per packaging material and a ratio per packaging shape/format, as published in the score-environnemental documentation (https://docs.score-environnemental.com/methodologie/produit/emballages).

1. fr_packaging_materials.csv (Matériaux, Score) -> %environmental_score_data{packaging_materials}

   Each material has a score. The Eco-score defines some entries that are in fact a
   shape + material combination (e.g. "Bouteille PET" = PET bottle); these are stored
   under composite keys "$material_id.$shape_id" (e.g. en:plastic.bottle) so they can be
   matched at compute time. The score is also attached to the packaging_materials
   taxonomy as the inherited property "environmental_score_score:en" so it can be
   resolved through taxonomy parents via get_inherited_property().

2. fr_packaging_shapes.csv (Format, Ratio) -> %environmental_score_data{packaging_shapes}

   Each shape has a ratio used to weight the material score by the packaging format.
   The ratio is attached to the packaging_shapes taxonomy as the inherited property
   "environmental_score_ratio:en".

Extra assignments map specific material/shape or shape keys to a source entry that already has a score (e.g. opaque pet bottle <- colored pet bottle, rPET bottle <- transparent rPET bottle, plastic <- other plastics, can <- drink-can, card <- backing, label <- sheet, spout <- bottle-cap, elo-pak <- tetra-pak).

load_environmental_score_data( $product_ref )

Loads data needed to compute the Environmental-Score.

compute_environmental_score( $product_ref )

compute_environmental_score() computes the Environmental-Score of a food product, and stores the details of the computation.

Arguments

Product reference $product_ref

Return values

The Environmental-Score score and computations details are stored in the product reference passed as input parameter.

Returned values:

- environmental_score_score : numeric Environmental-Score value - environmental_score_grade : corresponding A to E grade - environmental_score_data : Environmental-Score computation details

compute_environmental_score_agribalyse ( $product_ref )

compute_environmental_score() computes the Life Cycle Analysis (LCA) part of the Environmental-Score, based on the French AgriBalyse database.

Arguments

Product reference $product_ref

Return values

The LCA score and computations details are stored in the product reference passed as input parameter.

Returned values:

$product_ref->{agribalyse} hash with: -

$product_ref->{environmental_score_data}{missing} hash with: - categories if the product does not have a category - agb_category if the product does not have an Agribalyse match or proxy match for at least one of its categories.

compute_environmental_score_production_system_adjustment ( $product_ref )

Computes an adjustment (bonus or malus) based on production system of the product (e.g. organic).

Arguments

Product reference $product_ref

Return values

The adjustment value and computations details are stored in the product reference passed as input parameter.

Returned values:

$product_ref->{adjustments}{production_system} hash with: -

$product_ref->{environmental_score_data}{missing} hash with:

Notes

This function tests the presence of specific labels and categories that should not be renamed. They are listed in the t/environmental_score.t test file so that the test fail if they are renamed.

The labels are listed in the Environmental-Score documentation: https://docs.score-environnemental.com/methodologie/produit/label

compute_environmental_score_threatened_species_adjustment ( $product_ref )

Computes an adjustment (malus) if the ingredients are harmful to threatened species. e.g. threatened fishes, or ingredients like palm oil that threaten the habitat of threatened species.

Arguments

Product reference $product_ref

Return values

The adjustment value and computations details are stored in the product reference passed as input parameter.

Returned values:

$product_ref->{adjustments}{threatened_species} hash with: - value: malus (-10 for palm oil) - ingredient: the id of the ingredient responsible for the malus

aggregate_origins_of_ingredients ( $default_origins_ref, $aggregated_origins_ref, $ingredient_ref )

Computes adjustments(bonus or malus for transportation + EPI / Environmental Performance Index) according to the countries of origin of the ingredients.

Arguments

Default origins reference: $default_origins_ref

Array of origins specified in the origins field, that we will use for ingredients that do not have a specific origin.

Aggregated origins reference $aggregated_origins_ref

Data structure to which we will add the percentages for the ingredient specified in $ingredient_ref

Ingredient reference $ingredient_ref

Ingredient reference that may contains an ingredients structure for sub-ingredients.

Return values

The percentages are stored in $aggregated_origins_ref

get_country_origin_from_origins ( $origins_ref )

Given a list of origins, return the country for the first origin that is a country or a child of a country.

compute_environmental_score_origins_of_ingredients_adjustment ( $product_ref )

Computes adjustments(bonus or malus for transportation + EPI / Environmental Performance Index) according to the countries of origin of the ingredients.

The transportation bonus or malus is computed for all the countries where the Environmental-Score is enabled.

Arguments

Product reference $product_ref

Return values

The adjustment value and computations details are stored in the product reference passed as input parameter.

Returned values:

$product_ref->{adjustments}{origins_of_ingredients} hash with: - value_[country code]: combined bonus or malus for transportation + EPI - epi_value - transportation_value_[country code] - aggregated origins: sorted array of origin + percent to show the % of ingredients by country used in the computation

Note: the country EPI is not taken into account if the product already has a bonus for the production system.

compute_environmental_score_packaging_adjustment ( $product_ref )

Computes adjustments (malus) based on the packaging of the product.

Arguments

Product reference $product_ref

Return values

The adjustment value and computations details are stored in the product reference passed as input parameter.

Returned values:

$product_ref->{adjustments}{packaging} hash with: - value: malus for packaging - packagings: details of the computation

localize_environmental_score ( $cc, $product_ref)

The Environmental-Score and some of its components depend on the country of the consumer, as we take transportation to the consumer into account.

We compute the Environmental-Score for all countries, and this function copies the values for a specific country to the main Environmental-Score fields.

Note: even if we could not compute the Environmental-Score (because of a missing category), we still localize the origins of ingredients, so that it can be displayed in separate knowledge panels.

Arguments

Country code of the request $cc

Product reference $product_ref

Return values

The adjustment value and computations details are stored in the product reference passed as input parameter.

<<