Rainforest GFM
The Rainforest Gap Filling Module calculates the deforestation risk associated with food products by tracing the amount of critical commodities (soy and palm oil) from problematic sources. This includes not only ingredients that go directly into the end product but also soy and palm oil used in animal feed for livestock products.
Quick Reference
| Property | Description |
|---|---|
| Runs on | ModeledActivityNode with FoodProductFlowNode parent containing a product name |
| Dependencies | OriginGapFillingWorker |
| Key Input | Product name, origin country, certification status, product category |
| Output | rainforest_critical_products property with critical commodity quantities |
| Trigger | Product matched to critical commodity content data |
When It Runs
The module triggers when:
- A
ModeledActivityNodehas a parentFoodProductFlowNodewith a validproduct_name - The
OriginGapFillingWorkerhas completed (to ensure origin information is available) - The product is linked to critical commodity content data in the glossary
Key Output
The module adds a rainforest_critical_products property to the flow node containing:
- Quantity of critical commodities (grams per 100g of product)
- Certification status: Rainforest conservation certified, certified but not specified for rainforest, or not certified
Scientific Methodology
The deforestation calculation traces the amount of soy and palm oil from problematic sources that was required in the production of the food product. The methodology accounts for:
- Direct ingredients: Soy and palm oil used directly in the product
- Indirect ingredients: Soy and palm oil used in animal feed for livestock products
- Origin risk: Whether the product originates from high-deforestation-risk countries
- Certification: Whether the product has certifications that protect against deforestation
Critical Amount Calculation
The critical amount is calculated based on:
Critical Amount = Soy Content + Palm Oil Content
Where the soy content contribution depends on:
- Product origin country
- Product category (fish, beef/pork/chicken/egg/milk, or other)
- Location data source (FAO statistics versus specified origin)
Origin-Based Risk Assessment
The module applies different rules based on product origin:
For products with unknown origin:
- Full soy content is included (assumes worst-case sourcing)
- Full palm oil content is included
For fish products:
- Full soy content is included (regardless of origin)
- Full palm oil content is included
For beef, pork, chicken, egg, and milk products:
- Soy content included unless origin is Switzerland (CH)
- Full palm oil content is included
For other products:
- Soy content included only if origin is Brazil (BR), Argentina (AR), or China (CN)
- Full palm oil content is included
Implementation Details
Covered Commodities
The module tracks two primary deforestation-linked commodities:
| Commodity | Risk Factor | Primary Source Countries |
|---|---|---|
| Soy | Animal feed, direct ingredient | Brazil, Argentina, Paraguay, China |
| Palm Oil | Food processing, cosmetics | Indonesia, Malaysia |
Critical Product Categories
Soy-Critical Products
All meat products typically fed with concentrated feed are assigned soy content based on:
- Inventory data from Life Cycle Assessment databases
- Allocation to different animal products (meat types, dairy products)
- Plant-based products containing soy directly
Palm Oil-Critical Products
Products likely to contain palm oil with assigned amounts:
| Product Category | Palm Oil Content |
|---|---|
| Bread and pastries | 10% |
| Chicken/meat broth | 25% |
| Beef broth | 15% |
| Margarine | 26% |
| Plant-based fats/oils | 33% |
| Chocolate sweets (pralines) | variable |
Note: Soy or palm oil in amounts less than 1% by weight are ignored by the indicator.
Certification Categories
The module recognizes three certification states:
| Term XID | Category | Description |
|---|---|---|
EOS_rainforest_conservation_certified | Certified for rainforest | Product has certification specifically protecting rainforest |
EOS_certified_rainforest_not_specified | Certified, not rainforest specific | Product is certified but not specifically for rainforest conservation |
EOS_not_certified_for_rainforest | Not certified | No relevant certification |
High-Risk Countries
Soy Production Risk Countries
| Country Code | Country | Risk Level |
|---|---|---|
| BR | Brazil | High |
| AR | Argentina | High |
| CN | China | Moderate |
Additional countries to consider (noted in source): Paraguay, Russia, Bolivia
Palm Oil Production Risk Countries
Primary risk from Indonesia and Malaysia (implicit in palm oil content assignment).
Product Category Detection
The module detects specific product categories using FoodEx2 terms:
| Term XID | Category |
|---|---|
EOS_Fish-and-seafood | Fish products |
EOS_Beef-and-veal | Beef products |
EOS_Poultry | Chicken products |
EOS_Eggs | Egg products |
EOS_Dairy | Dairy products |
Recognized Certifications
Labels Protecting Against Deforestation
Based on labelinfo.ch (biodiversity indicator):
- Bio Knospe / Bio Suisse Knospe
- Coop Naturaplan / Coop Naturafarm
- Migros Bio / BIO natura / Bio Natur Plus
- Demeter
- KAGfreiland
- IP-Suisse
- Rainforest Alliance
- Fairtrade Max Havelaar
- EU-Bio / Bio-Siegel / Agriculture Biologique
Commodity-Specific Certifications
Soy: RTRS (Round Table on Responsible Soy) certified companies
Palm Oil: RSPO (Roundtable on Sustainable Palm Oil) member companies meeting WWF scorecard standards
Cocoa: Fairtrade, UTZ, Rainforest Alliance
Coffee: 4C Association, Fairtrade, Rainforest Alliance, UTZ, Organic
Full Code Reference
Critical Amount Calculation
The core logic for determining critical commodity amounts:
if (not flow_country_codes) or self.is_fish(amount_per_category_in_flow):
if not flow_country_codes:
warning_msg = (
f"No location found for product {parent_flow_product_name_terms}."
f"Assuming that the critical product comes from a problematic country."
)
logger.warn(warning_msg)
calc_graph.append_data_errors_log_entry(warning_msg)
critical_amount_per_100g = soy_content_per_100g + palm_oil_content_per_100g
else:
critical_amount_per_100g = palm_oil_content_per_100g
is_beef_pork_chicken_egg_milk = self.is_beef_pork_chicken_egg_milk(amount_per_category_in_flow)
for flow_country_code, source in zip(flow_country_codes, sources):
if flow_country_code and len(flow_country_code) == 3:
flow_country_code = iso_3166_map_3_to_2_letter(flow_country_code)
if not flow_country_code or not source:
critical_amount_per_100g += soy_content_per_100g / len(flow_country_codes)
elif source and source == LocationSourceEnum.fao_stat:
critical_amount_per_100g += soy_content_per_100g / len(flow_country_codes)
else:
if is_beef_pork_chicken_egg_milk:
if not flow_country_code == "CH":
critical_amount_per_100g += soy_content_per_100g / len(flow_country_codes)
else:
if flow_country_code in ("BR", "AR", "CN"):
critical_amount_per_100g += soy_content_per_100g / len(flow_country_codes)
Certification Detection
(
matched_certified_term_xids,
certified_term_containing_node,
) = parent_flow.get_prop_by_inheritance(
"tag_term_xids",
ignore_if=(
lambda prop_name, tag_term_xids_to_search=self.gfm_factory.certification_term_xids:
not has_one_of_predefined_tags(prop_name, tag_term_xids_to_search)
),
)
if (
matched_certified_term_xids
and certified_term_containing_node.product_name == parent_flow.product_name
):
for label_xid in matched_certified_term_xids:
if label_xid == "EOS_rainforest_conservation_certified":
certified = True
rainforest_specified = True
if label_xid == "EOS_certified_rainforest_not_specified":
certified = True
Output Property Creation
qty_prop = ReferencelessQuantityProp.unvalidated_construct(
value=critical_amount_per_100g,
unit_term_uid=self.gfm_factory.gram_term.uid,
)
if certified and rainforest_specified:
quantities = {self.gfm_factory.rainforest_conservation_certified.uid: qty_prop}
elif certified:
quantities = {self.gfm_factory.certified_rainforest_not_specified.uid: qty_prop}
else:
quantities = {self.gfm_factory.not_certified_for_rainforest.uid: qty_prop}
rainforest_critical_products = RainforestCriticalProductsProp.unvalidated_construct(
quantities=quantities,
for_reference=ReferenceAmountEnum.amount_for_100g
)
Calculation Example
Scenario: 100g of chicken breast from Germany
Step 1: Identify Product Category
- Product matches
EOS_Poultrycategory - Classified as beef/pork/chicken/egg/milk product
Step 2: Look Up Critical Content
- Soy content from feed: 15g per 100g (from glossary link)
- Palm oil content: 0g (not typically in chicken)
Step 3: Apply Origin Rules
- Origin: Germany (DE)
- Not Switzerland, so soy content is included
- Palm oil always included
Step 4: Calculate Critical Amount
Critical amount = 15g (soy) + 0g (palm oil) = 15g per 100g
Step 5: Determine Certification Status
- No certification tags found
- Status:
EOS_not_certified_for_rainforest
Final Output
The module adds to the flow node:
{
"rainforest_critical_products": {
"quantities": {
"[not_certified_for_rainforest_uid]": {
"value": 15.0,
"unit_term_uid": "[gram_uid]"
}
},
"for_reference": "amount_for_100g"
}
}
Regulatory Context
European Union Deforestation Regulation
The EU Deforestation Regulation (EUDR) entered into force on June 29, 2023, with application starting December 30, 2024 (June 30, 2025 for small enterprises).
Covered Commodities:
- Palm oil
- Soy
- Coffee
- Cocoa
- Cattle (beef)
- Timber
- Rubber
The regulation requires that products placed on the EU market must be:
- Deforestation-free (not produced on land deforested after December 31, 2020)
- Produced in accordance with relevant legislation of the country of production
- Covered by a due diligence statement
Known Limitations
Commodity Coverage
- Currently focuses primarily on soy and palm oil
- Cocoa and coffee not yet fully implemented despite regulatory relevance
- Timber and rubber not covered
Geographic Coverage
- Limited set of high-risk countries (Brazil, Argentina, China for soy)
- Paraguay, Russia, Bolivia noted as candidates for inclusion
- Sub-national risk differentiation not implemented
Certification Recognition
- System currently recognizes "certified" versus "not certified"
- Individual label recognition not fully implemented
- No differentiation between certification standards
Data Granularity
- Palm oil content assignments are category-based estimates
- Soy content in animal feed based on average inventory data
- No product-specific formulation data
Supply Chain Tracing
- Assumes worst-case sourcing when origin unknown
- FAO statistics-based origins treated as unknown
- No multi-tier supply chain visibility
References
-
World Resource Institute (2018). Global Forest Review - Deforestation linked to agriculture. https://research.wri.org/gfr/forest-extent-indicators/deforestation-agriculture
-
WWF (2020). Risky Business: The EU's dependence on imported biodiversity. https://forestsolutions.panda.org/uploads/default/report/WWF_Risky_business_eng.pdf
-
WWF (2021). Soy Scorecard - Assessing soy trader performance on deforestation-free production. https://wwfeu.awsassets.panda.org/downloads/wwf_soy_report_summary.pdf
-
WWF (2021). Palm Oil Buyers Scorecard. https://palmoilscorecard.panda.org/
-
WWF (2023). Chocolate Scorecard. https://www.wwf.de/fileadmin/fm-wwf/Publikationen-PDF/Landwirtschaft/chocolate-scorecard-2023.pdf
-
labelinfo.ch. Swiss label information platform - Biodiversity indicator. https://www.labelinfo.ch/
-
RTRS (2023). Chain of Custody certified companies. https://responsiblesoy.org/
-
European Commission (2023). Regulation (EU) 2023/1115 on deforestation-free products.