Saltar al contenido principal

VitaScore GFM

El Gap Filling Module VitaScore calcula los impactos en la salud humana de los productos alimentarios basándose en factores de riesgo dietético del estudio Global Burden of Disease (GBD). Convierte la composición de alimentos en Años de Vida Ajustados por Discapacidad (AVAD), permitiendo comparaciones de impacto en salud junto con métricas ambientales.

Referencia Rápida

PropiedadDescripción
Se ejecuta enFoodProductFlowNode
DependenciasAggregationGapFillingWorker, DailyFoodUnitGapFillingWorker
Entrada claveCantidades de categorías de alimentos, valores nutricionales, unidad de alimento diario
SalidaVitaScore en AVAD por factor de riesgo dietético
ActivadorEl producto tiene categorías de alimentos agregadas y unidad de alimento diario

Cuándo se Ejecuta

El módulo se activa cuando:

  1. La agregación de categorías de alimentos está completa
  2. El cálculo de Unidad de Alimento Diario (UAD) está completo
  3. El nodo tiene datos válidos de amount_per_category_in_flow
  4. El nodo tiene un valor válido de daily_food_unit

Salida Clave

El módulo produce:

  • VitaScore Total: Impacto agregado en salud en AVAD
  • Puntuaciones por factor: Contribuciones individuales de AVAD de cada factor de riesgo dietético
  • Versiones actual y heredada: Dos métodos de cálculo para comparación

Metodología Científica

VitaScore cuantifica el impacto en salud del consumo de alimentos usando Años de Vida Ajustados por Discapacidad (AVAD) basados en el estudio Global Burden of Disease. Un AVAD representa la pérdida de un año de salud plena.

Marco del Global Burden of Disease

El estudio GBD identifica factores de riesgo dietético que contribuyen a la carga de enfermedad. El VitaScore usa 13 factores de riesgo agrupados en dos categorías:

Factores de Riesgo Positivos (mayor consumo es beneficioso):

  • Dieta baja en frutas
  • Dieta baja en verduras
  • Dieta baja en cereales integrales
  • Dieta baja en frutos secos y semillas
  • Dieta baja en leche

Factores de Riesgo Negativos (mayor consumo es perjudicial):

  • Dieta alta en sodio
  • Dieta alta en carne procesada
  • Dieta alta en carne roja
  • Dieta alta en energía
  • Dieta alta en grasa
  • Dieta baja en grasa
  • Dieta alta en proteína
  • Dieta baja en proteína

Nivel de Exposición de Mínimo Riesgo Teórico (TMREL)

Cada factor de riesgo dietético tiene un rango de consumo óptimo llamado TMREL - el nivel de exposición que minimiza el riesgo para la salud. El VitaScore calcula cuánto se desvía el consumo real de este rango óptimo.

El TMREL se define por dos límites:

  • t_1: Límite inferior del rango óptimo
  • t_2: Límite superior del rango óptimo

La Fórmula del VitaScore

La fórmula central calcula una fracción de riesgo (f_r) para cada factor de riesgo dietético, luego multiplica por la carga de AVAD asociada:

Para factores positivos (donde consumir más es mejor):

f_r = (t_2 / (t_2 - t_1)) - x_r / (scaling * (t_2 - t_1))

Para factores negativos (donde consumir menos es mejor):

f_r = x_r / (scaling * (t_2 - t_1)) - (t_1 / (t_2 - t_1))

Donde:

  • x_r: Cantidad del factor de riesgo en el producto alimentario
  • t_1, t_2: Límites inferior y superior del TMREL
  • scaling: Factor de normalización (ver abajo)
  • f_r: Fracción de riesgo (limitada al rango 0-1)

Cálculo final:

VitaScore[r] = AVAD_r * f_r
VitaScore Total = suma(VitaScore[r] para todos los factores de riesgo)

Métodos de Normalización

El VitaScore soporta tres métodos de normalización para diferentes factores de riesgo:

MétodoDescripciónUso
per_dfuEscalar por Unidad de Alimento DiarioLa mayoría de factores de riesgo (frutas, verduras, carne, etc.)
per_total_energyEscalar por contenido energético totalGrasa y proteína como porcentaje de calorías
per_selfSin escalado (factor = 1,0)Mediciones directas

Unidad de Alimento Diario (UAD)

La Unidad de Alimento Diario representa la cantidad de consumo diario típica de una categoría de alimentos. Normaliza el cálculo de modo que el impacto en salud de un alimento sea proporcional a cuánto representa de la dieta diaria.


Detalles de Implementación

Factores de Riesgo Dietético Cubiertos

El módulo calcula impactos en salud para 13 factores de riesgo dietético. Cada factor tiene un Nivel de Exposición de Mínimo Riesgo Teórico (TMREL) que define el rango de consumo óptimo.

Factores de Riesgo Positivos (Mayor Consumo es Beneficioso)

Factor de RiesgoTMREL InferiorTMREL SuperiorUnidadNormalizaciónAVADReferencia de Guía Dietética
Dieta baja en frutas200300g/díaper_dfu61,24La OMS recomienda ≥400 g/día de frutas y verduras combinadas1
Dieta baja en verduras340500g/díaper_dfu30,57La OMS recomienda ≥400 g/día de frutas y verduras combinadas1
Dieta baja en cereales integrales100150g/díaper_dfu82,86Guías de EE.UU.: 3-4 porciones/día (~48-64 g)2
Dieta baja en frutos secos y semillas1625g/díaper_dfu13,98EAT-Lancet: ~50 g/día de frutos secos3
Dieta baja en leche350520g/díaper_dfu9,422-3 porciones de lácteos/día (~400-600 ml)4

Factores de Riesgo Negativos (Mayor Consumo es Perjudicial)

Factor de RiesgoTMREL InferiorTMREL SuperiorUnidadNormalizaciónAVADReferencia de Guía Dietética
Dieta alta en sodio (sal)15g/díaper_dfu29,43La OMS recomienda <5 g de sal/día (<2 g de sodio)5
Dieta alta en carne procesada04g/díaper_dfu96,94EAT-Lancet: evitar o minimizar carne procesada3
Dieta alta en carne roja1827g/díaper_dfu74,25EAT-Lancet: ~14 g/día (~100 g/semana)3

Factores de Riesgo de Macronutrientes (Energía y Porcentaje de Energía Total)

Factor de RiesgoTMREL InferiorTMREL SuperiorUnidadNormalizaciónAVADReferencia de Guía Dietética
Dieta alta en energía6501250kcalper_self88,66Una comida equilibrada: 450-850 kcal (~⅓ de 2200 kcal/día)4
Dieta alta en grasa27,5%50%% de kcalper_total_energy88,66Guías EFSA/EE.UU.: 20-35% de energía de grasa46
Dieta baja en grasa5%27,5%% de kcalper_total_energy88,66Guías EFSA/EE.UU.: 20-35% de energía de grasa46
Dieta alta en proteína22,5%60%% de kcalper_total_energy88,66AMDR de EE.UU.: 10-35% de energía de proteína6
Dieta baja en proteína0%22,5%% de kcalper_total_energy88,66AMDR de EE.UU.: 10-35% de energía de proteína6

Los valores de AVAD se expresan como AVAD por 100.000 personas-año y representan la carga de enfermedad atribuible a cada factor de riesgo dietético.

Conversión de Sodio a Sal

Dado que las guías dietéticas a menudo se refieren a sal (cloruro de sodio) en lugar de sodio, el módulo convierte los valores de sodio:

# El sodio es aproximadamente el 39,3% de la sal por masa
NA_PERCENT_IN_NACL = 39.337 # %

# Convertir sodio a equivalente de sal
salt_quantity = sodium_quantity * (100 / NA_PERCENT_IN_NACL)

Conversión de Energía de Macronutrientes

La grasa y proteína se convierten de masa a energía para cálculos de porcentaje de calorías:

FAT_CALORIES_PER_GRAM = 9.0      # kcal/g
PROTEIN_CALORIES_PER_GRAM = 4.0 # kcal/g

fat_kcal = fat_grams * FAT_CALORIES_PER_GRAM
protein_kcal = protein_grams * PROTEIN_CALORIES_PER_GRAM

Soporte de Versiones

El módulo mantiene dos versiones de cálculo:

VersiónDescripción
currentValores AVAD más recientes del GBD 2021
legacyValores AVAD originales para compatibilidad hacia atrás

Ambas versiones se calculan y almacenan, permitiendo comparación de resultados entre actualizaciones metodológicas.


Referencia Completa del Código

Flujo de Cálculo Principal

async def run(self, calc_graph: CalcGraph) -> None:
"""Realizar cálculo de vitascore."""
# Obtener categorías de alimentos agregadas y unidad de alimento diario
amount_per_category_in_flow_prop = self.node.amount_per_category_in_flow
dfu_prop = self.node.daily_food_unit

# Añadir sal y factores de riesgo derivados de nutrición
salt_qty, energy_qty, fat_qty, protein_qty = (
self.retrieve_salt_and_nutrition_amounts_for_activity_production_amount()
)

# Calcular vitascore para ambas versiones
for version in (VitascoreVersionEnum.legacy, VitascoreVersionEnum.current):
vitascore_for_local = self.compute_vitascore(
amount_per_category_in_flow_prop,
dfu_prop,
version,
ReferenceAmountEnum.amount_for_activity_production_amount,
)
# ... almacenar resultados

Implementación de la Fórmula Central del VitaScore

def vitascore_formula(
self,
food_category: QuantityPackageProp,
dfu: float,
legacy_or_current: str,
for_reference_amount: ReferenceAmountEnum,
) -> dict[UuidStr, ReferencelessQuantityProp]:
"""Fórmula para calcular vitascore."""
vitascore = {
self.gfm_factory.vitascore_term.uid: ReferencelessQuantityProp(
value=0.0, unit_term_uid=self.gfm_factory.daly_unit_term.uid
)
}

for idx, term in enumerate(
self.gfm_factory.positive_terms + self.gfm_factory.negative_terms
):
if term.xid in self.gfm_factory.used_categories_xid:
# Obtener límites TMREL de los datos del término
t_1 = float(term.data.get("tmrel").get("lower"))
t_2 = float(term.data.get("tmrel").get("upper"))
normalization = TmrelNormalizationEnum(
term.data.get("tmrel").get("tmrel_normalization")
)

# Obtener cantidad de categorías de alimentos
if term.uid in amount_per_category_in_flow_present:
x_r = float(amount_per_category_in_flow_present[term.uid].value)
else:
x_r = 0.0

# Obtener carga AVAD para este factor de riesgo
daly_r = float(term.data.get(legacy_or_current).get("amount"))

# Determinar factor de escalado
if normalization == TmrelNormalizationEnum.per_dfu:
scaling = dfu
elif normalization == TmrelNormalizationEnum.per_total_energy:
scaling = energy_kcal_value
elif normalization == TmrelNormalizationEnum.per_self:
scaling = 1.0

# Calcular fracción de riesgo
if scaling <= 0.0:
f_r = 0.0
else:
if idx < len(self.gfm_factory.positive_terms):
# Factores positivos: más es mejor
f_r = (t_2 / (t_2 - t_1)) - x_r / (scaling * (t_2 - t_1))
else:
# Factores negativos: menos es mejor
f_r = x_r / (scaling * (t_2 - t_1)) - (t_1 / (t_2 - t_1))

# Limitar fracción de riesgo a [0, 1]
f_r = max(0, min(1, f_r))

# Calcular y acumular vitascore
vitascore[term.uid] = ReferencelessQuantityProp(
value=daly_r * f_r,
unit_term_uid=self.gfm_factory.daly_unit_term.uid
)
vitascore[self.gfm_factory.vitascore_term.uid].value += daly_r * f_r

return vitascore

Recuperación de Sal y Nutrición

def retrieve_salt_and_nutrition_amounts_for_activity_production_amount(
self,
) -> Tuple[Optional[ReferencelessQuantityProp], ...]:
"""Extraer cantidades de sal y macronutrientes de los datos nutricionales."""

# Comprobar primero nutrientes agregados, luego valores de nutrientes
if aggregated_nutrients := self.node.aggregated_nutrients:
nutrition_pkg = aggregated_nutrients.amount_for_activity_production_amount()
elif nutrient_values := self.node.nutrient_values:
nutrition_pkg = nutrient_values.amount_for_activity_production_amount()

# Manejar división de cloruro de sodio
if nutrition_pkg and (sodium_chloride_term.uid in nutrition_pkg.quantities):
nutrition_pkg = split_sodium_chloride(nutrition_pkg)

# Convertir sodio a sal
if sodium_term.uid in nutrition_pkg.quantities:
salt_qty = nutrition_pkg.quantities[sodium_term.uid].duplicate()
salt_qty.value *= 100 / NA_PERCENT_IN_NACL

# Obtener energía y convertir grasa/proteína a kcal
energy_kcal_qty = nutrition_pkg.quantities.get(energy_term.uid)

if fat_mass_qty := nutrition_pkg.quantities.get(fat_term.uid):
fat_in_grams = convert_to_grams(fat_mass_qty)
fat_qty = ReferencelessQuantityProp(
value=fat_in_grams * FAT_CALORIES_PER_GRAM,
unit_term_uid=kcal_term.uid
)

if protein_mass_qty := nutrition_pkg.quantities.get(protein_term.uid):
protein_in_grams = convert_to_grams(protein_mass_qty)
protein_qty = ReferencelessQuantityProp(
value=protein_in_grams * PROTEIN_CALORIES_PER_GRAM,
unit_term_uid=kcal_term.uid
)

return salt_qty, energy_kcal_qty, fat_qty, protein_qty

Ejemplo de Cálculo

Escenario: Calcular VitaScore para 100g de jamón procesado

Paso 1: Identificar Cantidades de Factores de Riesgo

De la agregación de categorías de alimentos:

  • Carne procesada: 100g
  • Carne roja: 0g (contada separadamente de procesada)
  • Frutas: 0g
  • Verduras: 0g

De los valores nutricionales:

  • Sodio: 1200mg (se convierte a 3050mg de sal)
  • Energía: 145 kcal
  • Grasa: 8g (72 kcal)
  • Proteína: 18g (72 kcal)

Paso 2: Calcular Fracciones de Riesgo

Dieta alta en carne procesada (factor negativo):

  • TMREL: 0-0g por día (lo óptimo es cero consumo)
  • Escalado: Unidad de Alimento Diario (asumiendo 2000g de ingesta diaria de alimentos)
  • Cantidad normalizada: 100g / 2000g = 0,05 (5% de la ingesta diaria)
  • Fracción de riesgo: Calculada según desviación del TMREL

Dieta alta en sodio:

  • TMREL: 1000-5000mg por día
  • Cantidad de sal: 3050mg
  • Fracción de riesgo: Basada en dónde cae 3050mg en el rango TMREL

Dieta baja en frutas (factor positivo):

  • Cantidad: 0g
  • Fracción de riesgo: Máxima (sin contenido de fruta)

Paso 3: Aplicar Valores AVAD

Cada fracción de riesgo se multiplica por la carga AVAD asociada de los datos GBD:

  • Carga AVAD de carne procesada: ~40 AVAD por 100.000 personas-año
  • Carga AVAD de sodio: ~30 AVAD por 100.000 personas-año

Paso 4: Sumar VitaScore Total

VitaScore Total = suma de (AVAD_r * f_r) para los 13 factores de riesgo

El resultado se expresa en micro-AVAD por porción, representando la carga proporcional en salud.


Fuentes de Datos

Estudio Global Burden of Disease

El VitaScore se basa en el estudio GBD 2021:

GBD 2021 Risk Factors Collaborators (2024). Global burden and strength of evidence for 88 risk factors in 204 countries and 811 subnational locations, 1990-2021: a systematic analysis for the Global Burden of Disease Study 2021. The Lancet.

Datos clave extraídos:

  • Cargas AVAD para cada factor de riesgo dietético
  • Rangos TMREL para consumo óptimo
  • Estimaciones de riesgo relativo

Valores TMREL

Los Niveles de Exposición de Mínimo Riesgo Teórico provienen de:

  1. Apéndice 1 del GBD 2021: Especificaciones detalladas de TMREL para cada factor de riesgo
  2. Materiales Suplementarios de Lancet: Datos de apoyo para la derivación del TMREL

Factores de Mediación

El GBD usa factores de mediación para tener en cuenta vías de riesgo superpuestas. Por ejemplo, la carne roja impacta la salud tanto directamente como a través de su efecto sobre el índice de masa corporal (IMC).


Limitaciones Conocidas

Restricciones Metodológicas

  • Promedios poblacionales: Los valores AVAD representan promedios globales o regionales, no riesgo individual
  • Especificidad por edad/género: La implementación actual usa valores para toda la población (valores específicos por edad/género disponibles pero no implementados)
  • Superposición de factores de riesgo: Los factores de mediación abordan parcialmente pero no completamente los riesgos correlacionados

Limitaciones de Datos

  • Coincidencia de alimentos: Requiere clasificación precisa de categorías de alimentos
  • Completitud nutricional: Los cálculos de sodio/grasa/proteína dependen de datos nutricionales completos
  • Incertidumbre del TMREL: Los rangos de consumo óptimo tienen incertidumbre científica inherente

Lagunas de Cobertura

  • Especificidad por país: Los valores AVAD pueden hacerse específicos por país pero actualmente usan estimaciones globales
  • Alimentos procesados: Los alimentos procesados complejos pueden tener mapeo de categorías incompleto
  • Alimentos novedosos: Las nuevas categorías de alimentos pueden carecer de asociaciones establecidas de factores de riesgo

Referencias

  1. GBD 2021 Risk Factors Collaborators (2024). Global burden and strength of evidence for 88 risk factors in 204 countries and 811 subnational locations, 1990-2021. The Lancet, 403(10440), 2162-2203.

  2. Eaternity (2017). VitaScore Documentation. https://eaternity.org/assets/smart-chefs/2017-12-12_VitaScore_Documentation_web.pdf

  3. Ernstoff, A., et al. (2020). Towards Win-Win Policies for Healthy and Sustainable Diets. Nutrients, 12(9), 2745.

  4. Murray, C.J.L., et al. (2020). Global burden of 87 risk factors in 204 countries and territories, 1990-2019: a systematic analysis for the Global Burden of Disease Study 2019. The Lancet, 396(10258), 1223-1249.

  5. GBD Results Tool. Institute for Health Metrics and Evaluation. https://vizhub.healthdata.org/

Footnotes

  1. Hoja Informativa de Dieta Saludable de la OMS 2

  2. Guías Dietéticas de EE.UU. y Cereales Integrales

  3. Dieta de Salud Planetaria EAT-Lancet 2 3

  4. Valores de Referencia Dietéticos de EFSA 2 3 4

  5. Reducción de Sodio de la OMS

  6. Guías Dietéticas de EE.UU. - Rangos Aceptables de Distribución de Macronutrientes 2 3 4