Environmental impact estimation of Open Food Facts products

This repository contains a Python program to estimate the environmental impact of the agricultural steps of a product of the Open Food Facts database.

✔️ What this tool does

This tool gives an estimation of the environmental impact of the agricultural steps of a product by browsing its possible recipes according to its ingredient list and nutritional composition.

❌ What this tool does NOT do

  • Giving the exact environmental impact of a product

  • Taking into account the origin of the ingredients

  • Taking into account the packaging of the product

  • Making a complete Life Cycle Assessment of the product

  • Reverse engineering the recipe of the product

Installation

This program uses the PySCIPOpt package and the SCIP Optimization Suite V7.0. Installation instructions can be found here (PySCIPOpt) and here (SCIP).

See requirements.txt for the other required Python packages.

Usage

Impact estimation of a product can be done using impacts_estimation.estimate_impacts().

from impacts_estimation import estimate_impacts
from openfoodfacts import get_product

product = get_product(barcode='3175681790285')['product']

impact_categories = ['EF single score',
                     'Climate change']

impact_estimation_result = estimate_impacts(product=product,
                                            impact_names=impact_categories)

for impact_category in impact_categories:
    print(f"{impact_category}: "
          f"{impact_estimation_result['impacts_geom_means'][impact_category]:.4} "
          f"{impact_estimation_result['impacts_units'][impact_category]}")
# EF single score: 0.03832 mPt
# Climate change: 0.3819 kg CO2 eq

If safe_mode is set to True, it will change the parameters in case of error to ensure getting a result.

from impacts_estimation import estimate_impacts, RecipeCreationError
from openfoodfacts import get_product

product = get_product(barcode='3564707104920')['product']

try:
    impact_estimation_result = estimate_impacts(product=product,
                                                impact_names='EF single score',
                                                safe_mode=False)
except RecipeCreationError:
    print("No possible recipe with the given input data.")
# No possible recipe with the given input data.

impact_estimation_result = estimate_impacts(product=product,
                                            impact_names='EF single score',
                                            safe_mode=True)

print(impact_estimation_result['impacts_geom_means']['EF single score'])
# 0.16486248336651319

print(impact_estimation_result['warnings'])
# ['from impacts_estimation import estimate_impacts, RecipeCreationError
from openfoodfacts import get_product

product = get_product(barcode='3564707104920')['product']

try:
    impact_estimation_result = estimate_impacts(product=product,
                                                impact_names='EF single score',
                                                safe_mode=False)
except RecipeCreationError:
    print("No possible recipe with the given input data.")
# No possible recipe with the given input data.

impact_estimation_result = estimate_impacts(product=product,
                                            impact_names='EF single score',
                                            safe_mode=True)

print(impact_estimation_result['impacts_geom_means']['EF single score'])
# 0.050604882643004834

print(impact_estimation_result['warnings'])
# ['Parameter use_defined_prct has been set to False in order to get a result.']']

The reporting module can be used to create HTML impact estimation reports.

from reporting import ProductImpactReport

reporter = ProductImpactReport(barcode='3292590830953')

reporter.to_html()

Parameters

The function impacts_estimation.estimate_impacts() accepts the following parameters:

Parameter

Type

Default

Description

product

dict

Open Food Facts product to analyze

impact_names

string or iterable

Names of the impacts to compute in French or in English. They must correspond to the impact categories used by Agribalyse. See list of available impact categories.

quantity

float

100

Quantity of product in grams for which the impact must be calculated. If None, will use the ‘product_quantity’ attribute of the product. If ‘product_quantity’ is undefined, will use 100g by default.

ignore_unknown_ingredients

bool

True

Should ingredients absent of OFF taxonomy and without defined percentage be considered as parsing errors and ignored?

min_run_nb

int

30

Minimum number of runs for the Monte-Carlo loop

max_run_nb

int

1000

Maximum number of runs for the Monte-Carlo loop

forced_run_nb

int

None

Used to bypass natural Monte-Carlo stopping criteria and force the number of runs

confidence_interval_width

float

0.05

Width of the confidence interval that will determine the convergence detection. See documentation for more information.

confidence_level

float

0.95

Confidence level of the confidence interval.

use_nutritional_info

bool

True

Should nutritional information be used to estimate recipe?

maximum_evaporation

float

0.8

Upper bound of the evaporation coefficient [0-1[. I.e. maximum proportion of ingredients water that can evaporate.

total_mass_used

float

None

Total mass of ingredients before cooking (including water) used in grams, if known.

min_prct_dist_size

int

30

Minimum size of the reference ingredients percentage distribution that will be used to pick a proportion for an ingredient. If the distribution (adjusted to the possible value interval) has less data, uniform distribution will be used instead. See documentation for more information.

dual_gap_type

str

‘absolute’

‘absolute’ or ‘relative’. Determines the precision type of the variable optimization by the solver.

dual_gap_limit

float

0.001

Determines the precision of the variable optimization by the solver. Relative or absolute according to dual_gap_type.

solver_time_limit

float

60

Maximum time for the solver optimization (in seconds). Set to None or 0 to set no limit.

time_limit_dual_gap_limit

float

0.01

Accepted precision of the solver in case of time limit hit. Relative or absolute according to dual_gap_type

use_ingredients_impact_uncertainty

bool

True

Should ingredients impacts uncertainty data be used?

confidence_weighting

bool

True

Should the recipes be weighted by their confidence score (deviation of the recipes nutritional composition to the reference product’s nutritional composition). See documentation for more information.

quantiles_points

iterable

(0.05, 0.25, 0.5, 0.75, 0.95)

List of impacts quantiles cutting points to return in the result.

distributions_as_result

bool

False

Should the recipes, the distributions of their impacts, the mean confidence interval and the confidence score be added to the result?

confidence_score_weighting_factor

float

10

Weighting factor used for the confidence score calculation. It corresponds to the weight of the nutritional distance against the absolute difference between the total mass and 100g/100g. See documentation for more information.

safe_mode

bool

True

If set to True, the constraints will be progressively relaxed in order to get a result.

Result

The result of impacts_estimation.estimate_impacts() is a dictionary containing the calculated impacts as well as several additional data.

Key

Description

impact_geom_means

Geometric means of the impacts of all sampled recipes in each impact category. The main result.

impact_geom_stdevs

Geometric standard deviations of the impacts of all sampled recipes in each impact category.

impacts_quantiles

Quantiles of the impacts of all sampled recipes in each impact category. Cutting points are defined by quantiles_points.

impacts_relative_interquartile

Relative interquartile of the impacts of all sampled recipes in each impact category. Useful to estimate the spread of the possible impact.

ingredients_impact_share

Average share of the impact carried by each ingredient for each impact category.

impacts_units

Units in which the impacts are expressed.

product_quantity

Quantity of product in grams for which the impact have been calculated.

warnings

List of possible text warnings.

ignored_unknown_ingredients

List of ingredients that have been ignored if ignore_unknown_ingredients have been set to True.

uncharacterized_ingredients

List of ingredients with no data about nutrition and/or environmental impact.

uncharacterized_ingredients_ratio

Ratio ingredients with no data about nutrition and/or environmental impact.

uncharacterized_ingredients_mass_proportion

Average mass proportion of ingredients with no data about nutrition and/or environmental impact.

number_of_runs

Number of runs before impact convergence.

number_of_ingredients

Number of ingredients of the product.

calculation_time

Impact calculation time.

impact_distributions

Distributions of the impacts of all sampled recipes in each impact category.

mean_confidence_interval_distribution

Distributions of the confidence interval of the mean of the impacts of all sampled recipes in each impact category.

confidence_score_distribution

Distributions of the confidence score of all sampled recipes.

Available environmental impact categories

The ingredients environmental impact data come from *Agribalyse*. The impact categories are:

French name

English name

Score unique EF

EF single score

Changement climatique

Climate change

Appauvrissement de la couche d’ozone

Ozone depletion

Rayonnements ionisants

Ionizing radiations

Formation photochimique d’ozone

Photochemical ozone formation

Particules

Particulate matter

Acidification terrestre et eaux douces

Terrestrial and freshwater acidification

Eutrophisation terreste

Terrestrial eutrophication

Eutrophisation eaux douces

Freshwater eutrophication

Eutrophisation marine

Marine eutrophication

Utilisation du sol

Land use

Écotoxicité pour écosystèmes aquatiques d’eau douce

Freshwater ecotoxicity

Épuisement des ressources eau

Water depletion

Épuisement des ressources énergétiques

Resource use, energy carriers

Épuisement des ressources minéraux

Resource use, minerals and metals

Algorithm

The algorithm used by this program is based on a Monte-Carlo approach to estimate the impact of a product. Its principle is to pick random possible recipes of the product and compute their impact until the geometric mean of the impacts of all sampled recipes stabilizes within a given confidence interval. The sampling of possible recipes is made as accurate as possible by using a non-linear programming solver (SCIP), and nutritional information of the product.

Documentation

off-product-environmental-impact.readthedocs.io

Contributing

For contribution guidelines, please see CONTRIBUTING.md.

Testing

This project can be tested using pytest on the automated tests contained in the /tests/ directory.

Disclaimer

The results given by this tool are estimates of the environmental impact of a food product. These estimates are subject to potential bias and uncertainties due to the stochastic nature of the algorithm and the uncertainty inherent to the background data. Thus, the accuracy of the result cannot be guaranteed.

Hardware compatibility issues

Hardware compatibility issue have been observed for this software on a 2012 MacBook Pro (2.5 GHz Dual-Core Intel Core i5) running macOS Catalina.

References

*ADEME - Agribalyse*, 2020

*Anses - Table de composition nutritionnelle des aliments Ciqual*, 2020

*Santé Canada - Fichier canadien sur les éléments nutritifs* , 2015

*The SCIP Optimization Suite*