Zum Hauptinhalt springen

Gap Filling Modules (GFMs)

Gap Filling Modules sind die Bausteine der EOS-Berechnungs-Engine. Jedes Modul ist eine spezialisierte, in sich geschlossene Einheit, die einen bestimmten Aspekt der Umweltauswirkungsberechnung behandelt.

Was sind Gap Filling Modules?

In der realen Welt sind Lebensmittelproduktdaten oft unvollständig. Ein Produkt könnte haben:

  • Einen Namen, aber keine Zutatenliste
  • Zutaten, aber keine Herkunftsinformationen
  • Herkunft, aber keine Transportdetails
  • Teilweise Nährwertdaten

GFMs lösen dieses Problem, indem sie automatisch "Lücken" in Produktdaten füllen, unter Verwendung wissenschaftlicher Modelle, Datenbanken und intelligenter Standardwerte.

Das GFM-Konzept

1f8ebcf3dc1e2fe617c89994d040d010

Jedes GFM besteht aus:

  1. Planungslogik - Bestimmt, ob das Modul für einen gegebenen Knoten relevant ist
  2. Bereitschaftsprüfung - Verifiziert, dass alle Abhängigkeiten erfüllt sind
  3. Ausführung - Die Berechnungslogik, die Lücken füllt und den Graphen aktualisiert

Verfügbare Module

EOS enthält 28 spezialisierte GFMs, nach Funktion organisiert:

Matching-Module

Gleichen Produktnamen und Zutaten mit Datenbankeinträgen ab:

ModulZweck
match_product_name_gfmGleicht Produktnamen mit Datenbankeinträgen ab
attach_food_tags_gfmFügt Lebensmittelklassifizierungs-Tags hinzu
link_term_to_activity_node_gfmVerknüpft Begriffe mit LCA-Aktivitäten
link_food_categories_gfmWeist Lebensmittelkategorien zu

Standortmodule

Verarbeiten geografische und Herkunftsdaten:

ModulZweck
origin_gfmBestimmt Produktherkunft
location_gfmVerarbeitung geografischer Standorte
transportation_decision_gfmBestimmt Transportmodi
transportation_mode_distance_gfmBerechnet Transportentfernungen

Lebenszyklusmodule

Modellieren Verarbeitung und Lieferkette:

ModulZweck
processing_gfmAuswirkungen der Lebensmittelverarbeitung
greenhouse_gfmTreibhausgasberechnungen
conservation_gfmLagerung und Konservierung
perishability_gfmHaltbarkeits- und Abfallfaktoren

Auswirkungsbewertungsmodule

Berechnen Umweltmetriken:

ModulZweck
impact_assessment_gfmAggregiert Auswirkungsberechnungen
water_scarcity_gfmWasserfußabdruckberechnung
rainforest_gfmEntwaldungsauswirkung
vitascore_gfmErnährungsbewertung

Aggregationsmodule

Kombinieren Ergebnisse über Zutaten hinweg:

ModulZweck
aggregation_gfmAggregiert Zutatenauswirkungen
ingredient_splitter_gfmZerlegt zusammengesetzte Zutaten
ingredient_amount_estimator_gfmSchätzt Zutatenmengen

Modularchitektur

Jedes GFM folgt dem Factory/Worker-Muster:

# Factory - einmal pro Service initialisiert, verwaltet Worker
class ExampleGapFillingFactory(AbstractGapFillingFactory):
def __init__(self, postgres_db, service_provider):
super().__init__(postgres_db, service_provider)
self.cache = {} # Persistenter Cache über Berechnungen

async def init_cache(self):
# Erforderliche Daten in Speicher laden
pass

def spawn_worker(self, node):
return ExampleGapFillingWorker(node)

# Worker - pro Knoten erzeugt, führt die Berechnung aus
class ExampleGapFillingWorker(AbstractGapFillingWorker):
def should_be_scheduled(self) -> bool:
# Ist dieses GFM für diesen Knoten relevant?
return self.node.needs_processing()

def can_run_now(self) -> GapFillingWorkerStatusEnum:
# Sind Abhängigkeiten erfüllt?
if self.node.has_required_data():
return GapFillingWorkerStatusEnum.ready
return GapFillingWorkerStatusEnum.reschedule

async def run(self, calc_graph):
# Gap-Filling-Logik ausführen
result = await self.calculate()
self.node.set_property("result", result)

Warum Factory/Worker?

VorteilBeschreibung
IsolationJede Berechnung läuft in eigener Worker-Instanz
CachingFactory verwaltet Caches über Berechnungen hinweg
SkalierbarkeitWorker können verteilt werden
TestbarkeitWorker können unabhängig getestet werden

Orchestrierung

Der Orchestrator koordiniert die GFM-Ausführung:

310e59fe1e00f276abc9c098d413a392

Planungsschleife

  1. Knotenhinzufügung - Wenn Knoten zum CalcGraph hinzugefügt werden, erzeugt der Orchestrator Worker
  2. Planungsprüfung - Jedes Workers should_be_scheduled() wird aufgerufen
  3. Bereitschaftsprüfung - can_run_now() verifiziert Abhängigkeiten
  4. Ausführung - Bereite Worker werden asynchron ausgeführt
  5. Graph-Updates - Ergebnisse werden in Knoteneigenschaften geschrieben
  6. Propagation - Neue Knoten können zusätzliche GFMs auslösen

Modulabhängigkeiten

Module hängen von Ausgaben anderer Module ab:

8c045e0d20b376c7fec0bb3b18d4637f

Abhängigkeiten werden automatisch durch die Planungsschleife des Orchestrators aufgelöst.

Zustandsverwaltung

GFMs verfolgen ihren Ausführungszustand pro Knoten:

# Pro-Knoten-Zustand in GfmStateProp (worker_states) gespeichert
# Werte sind aus NodeGfmStateEnum: "S" (geplant), "F" (abgeschlossen), "C" (abgebrochen)
gfm_state = {
"MatchProductNameGapFillingWorker": "F", # abgeschlossen
"OriginGapFillingWorker": "F", # abgeschlossen
"GreenhouseGapFillingWorker": "S", # geplant (läuft)
"ImpactAssessmentGapFillingWorker": "S" # geplant (ausstehend)
}

Zustandswerte

Der GFM-Zustand wird mit NodeGfmStateEnum verfolgt:

ZustandCodeBeschreibung
scheduledSGFM ist für Ausführung auf diesem Knoten geplant
finishedFGFM wurde erfolgreich abgeschlossen
canceledCGFM wurde abgebrochen (nicht anwendbar oder fehlgeschlagen)

Fehlerbehandlung

GFMs implementieren sorgfältige Fehlerbehandlung:

async def run(self, calc_graph):
try:
result = await self.calculate()
self.node.set_property("result", result)
except Exception as e:
# Fehler mit Kontext protokollieren
logger.error("GFM fehlgeschlagen",
gfm=self.__class__.__name__,
node_uid=self.node.uid,
error=str(e))
# DataError zur Verfolgung erstellen
error = DataError(
node_uid=self.node.uid,
gfm_name=self.__class__.__name__,
message=str(e),
classification=ErrorClassification.calculation_error
)
self.node.add_error(error)

Fallback-Strategie

Wenn ein Modul fehlschlägt:

  1. Fehler protokollieren - Strukturierte Protokollierung mit Kontext
  2. DataError erstellen - Zur Berichterstattung verfolgen
  3. Verarbeitung fortsetzen - Andere Module können weiterhin laufen
  4. Unsicherheit markieren - Ergebnis mit reduziertem Vertrauen markieren

Nächste Schritte