Files
site/WESP_REL/app/lab/norm_catalog.py
T
2026-07-17 12:57:18 +03:00

291 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Каталог показателей норм профиля стада."""
from __future__ import annotations
import re
import unicodedata
from app.lab.indicators import RATION_ALL_INDICATORS, calc_indicator_keys
_CALC_META = {d["key"]: d for d in RATION_ALL_INDICATORS}
# Заголовок колонки CSV «Нормы Дойн/КРС» (после нормализации) → indicator_key в lab_profile_norm
NORM_HEADER_TO_KEY: dict[str, str] = {
"Сухое Вещество": "dry_matter",
"Сыр. Протеин": "crude_protein",
"уСП": "usp",
"RNB": "rnb",
"БРА": "rnb",
"ЧЭЛ- КРС": "nel",
"ОЭ-КРС": "oe",
"Сырая клетч": "ndf",
"Сырая клетчат": "ndf",
"Сырая клетчатка": "ndf",
"Структур клетчатк": "structural_fiber",
"Сырой жир": "crude_fat",
"Сирой жир": "crude_fat",
"Ca": "calcium",
"P": "phosphorus",
"Mg": "magnesium",
"Na": "sodium",
"DCAB": "dcab",
"Сахар и Крохм": "sugar_starch",
"Нераств. Крохмал": "insoluble_starch",
"Нерозч. Крохмал": "insoluble_starch",
"Сахар": "sugar",
"Крохмал": "starch",
"Каротин": "carotene",
"b -Каротин": "beta_carotene",
"Линолевая к-та": "linoleic_acid",
"Линоленовая ки-та": "linolenic_acid",
"Масляная ки-та": "butyric_acid",
"Мочевина": "urea",
"СВ Основной корм": "dm_main",
"КРС Орг Вещ": "tdn_cattle",
"Перевар Орг Вещ": "digestible_organic_matter",
"КРС Протеин": "cp_cattle",
"Перевар Протеин": "digestible_protein",
"КРС Сирий жир": "fat_cattle",
"КРС Сирой жир": "fat_cattle",
"Перевар Сырой жир": "digestible_fat",
"Перевар Сирой жир": "digestible_fat",
"КРС Сырая клетч": "fiber_cattle",
"Перевар сыр клетч": "digestible_fiber",
"КРС БЭВ": "nfe_cattle",
"Перевар БЭВ": "digestible_nfe",
"ВЕ": "feed_value",
"НДК Общ": "ndf_total",
"НДК Осн. Корм": "ndf_main_feed",
"КДК общ": "adf_total",
"% нераств. протеин": "insoluble_protein_pct",
"Нераствор протеин": "insoluble_protein",
"СЖ/кг СВ": "fat_per_kg_dm",
"НСП/кг СВ": "nsp_per_kg_dm",
"СП/кг СВ": "cp_per_kg_dm",
"пОВ/кг СВ": "dom_per_kg_dm",
"пСЖ/кг СВ": "digestible_fat_per_kg_dm",
"уСП<7%CЖ": "usp_low_fat",
"уСП>7%CЖ": "usp_high_fat",
"уСП/кг СВ": "usp_per_kg_dm",
"уСП в ОВ": "usp_in_om",
"Нераств крохмал": "insoluble_starch_alt",
"Метаб ОЕТ": "metab_oet",
"Метаб лизин": "metab_lysine",
"Метабол Треон": "metab_threonine",
"Метаб Лейц": "metab_leucine",
"Метаб Изол": "metab_isoleucine",
"Метаб Вал": "metab_valine",
"НДК % від СВ ()": "ndf_pct_dm_uk",
"НДК % от СВ ()": "ndf_pct_dm",
"НДК-ОК % від СВ ()": "ndf_main_pct_dm_uk",
"НДК-ОК % от СВ ()": "ndf_main_pct_dm",
"КДК % від СВ ()": "adf_pct_dm_uk",
"КДК % от СВ ()": "adf_pct_dm",
"НКВ % від СВ ()": "nfc_pct_dm_uk",
"НКВ % от СВ ()": "nfc_pct_dm",
"SW / кг СВ ()": "sw_per_kg_dm",
"ЧЕЛ/кг СВ (МДж)": "nel_per_kg_dm",
"Нер. СП / кг СВ": "rup_per_kg_dm",
"%СК/кг СВ ()": "fiber_pct_per_kg_dm",
"%-СЖ/кг СВ ()": "fat_pct_per_kg_dm",
"%-уСП / кг СВ ()": "usp_pct_per_kg_dm",
"% уСП/кг СВ": "usp_pct_dm",
"%-Ca / кг СВ ()": "ca_pct_per_kg_dm",
"%-P / кг СВ ()": "p_pct_per_kg_dm",
"%-К / кг СВ ()": "k_pct_per_kg_dm",
"%-Na / кг СВ ()": "na_pct_per_kg_dm",
"%-Mg / кг СВ ()": "mg_pct_per_kg_dm",
"% стр Сыр. Клетчатк.": "structural_fiber_pct",
"% стр Сыр. Клетч.": "structural_fiber_pct",
"% Крохмал. СВ": "starch_pct_dm",
"% Нераств крохм": "insoluble_starch_pct",
"Са:P": "ca_p_ratio",
"K:Na": "k_na_ratio",
"Рацион % СВ от Веса КРС": "ration_dm_pct_bw",
"Рацион % от Веса КРС": "ration_pct_bw",
"Витамин А": "vitamin_a",
"Витамин D": "vitamin_d",
"Витамин Е": "vitamin_e",
"Витамин В1": "vitamin_b1",
"Витамин В2": "vitamin_b2",
"Витамин В6": "vitamin_b6",
"Витамин В12": "vitamin_b12",
"Пантеонат Кальция": "calcium_pantothenate",
"Пантеонат Кальцию": "calcium_pantothenate",
"Никотиновая кислота": "niacin",
"Фолиева кислота": "folic_acid",
"Фолиевач кислота": "folic_acid",
"Холин": "choline",
"Биотин": "biotin",
"Fe": "iron",
"Zn": "zinc",
"Cu": "copper",
"Co": "cobalt",
"Mn": "manganese",
"Se": "selenium",
"J": "iodine",
"K": "potassium",
"Сахар и усв. крох": "sugar_digestible_starch",
"Сырая зола": "crude_ash",
"Сірая зола": "crude_ash",
"БЭВ": "nfe",
"БЄВ": "nfe",
"Арахидоновая ки-та": "arachidonic_acid",
"Полиэновая ки-та": "polyenoic_acid",
"OET": "oet",
"Синтез Мдж": "synthesis_mj",
}
# Метаданные для UI (label/unit) — показатели вне расчёта рациона
_EXTRA_NORM_META: dict[str, dict[str, str]] = {
"beta_carotene": {"label": "β-каротин", "unit": "мг"},
"linoleic_acid": {"label": "Линолевая к-та", "unit": "г"},
"linolenic_acid": {"label": "Линоленовая к-та", "unit": "г"},
"butyric_acid": {"label": "Масляная к-та", "unit": "г"},
"urea": {"label": "Мочевина", "unit": "г"},
"tdn_cattle": {"label": "КРС орг. вещество", "unit": "г"},
"digestible_organic_matter": {"label": "Перевар. орг. вещество", "unit": "г"},
"cp_cattle": {"label": "КРС протеин", "unit": "г"},
"digestible_protein": {"label": "Перевар. протеин", "unit": "г"},
"fat_cattle": {"label": "КРС сырой жир", "unit": "г"},
"digestible_fat": {"label": "Перевар. сырой жир", "unit": "г"},
"fiber_cattle": {"label": "КРС сырая клетчатка", "unit": "г"},
"digestible_fiber": {"label": "Перевар. сырая клетчатка", "unit": "г"},
"nfe_cattle": {"label": "КРС БЭВ", "unit": "г"},
"digestible_nfe": {"label": "Перевар. БЭВ", "unit": "г"},
"feed_value": {"label": "ВЕ", "unit": ""},
"ndf_total": {"label": "НДК общ", "unit": "г"},
"ndf_main_feed": {"label": "НДК осн. корм", "unit": "г"},
"adf_total": {"label": "КДК общ", "unit": "г"},
"insoluble_protein_pct": {"label": "% нераств. протеин", "unit": "%"},
"fat_per_kg_dm": {"label": "СЖ/кг СВ", "unit": "г"},
"nsp_per_kg_dm": {"label": "НСП/кг СВ", "unit": "г"},
"cp_per_kg_dm": {"label": "СП/кг СВ", "unit": "г"},
"dom_per_kg_dm": {"label": "пОВ/кг СВ", "unit": "г"},
"digestible_fat_per_kg_dm": {"label": "пСЖ/кг СВ", "unit": "г"},
"usp_low_fat": {"label": "уСП <7% СЖ", "unit": "г"},
"usp_high_fat": {"label": "уСП >7% СЖ", "unit": "г"},
"usp_per_kg_dm": {"label": "уСП/кг СВ", "unit": "г"},
"usp_in_om": {"label": "уСП в ОВ", "unit": "г"},
"insoluble_starch_alt": {"label": "Нераств. крахмал (2)", "unit": "г"},
"metab_oet": {"label": "Метаб. ОЕТ", "unit": "г"},
"metab_lysine": {"label": "Метаб. лизин", "unit": "г"},
"metab_threonine": {"label": "Метаб. треонин", "unit": "г"},
"metab_leucine": {"label": "Метаб. лейцин", "unit": "г"},
"metab_isoleucine": {"label": "Метаб. изолейцин", "unit": "г"},
"metab_valine": {"label": "Метаб. валин", "unit": "г"},
"ndf_pct_dm": {"label": "НДК % от СВ", "unit": "%"},
"ndf_pct_dm_uk": {"label": "НДК % від СВ", "unit": "%"},
"ndf_main_pct_dm": {"label": "НДК-ОК % от СВ", "unit": "%"},
"ndf_main_pct_dm_uk": {"label": "НДК-ОК % від СВ", "unit": "%"},
"adf_pct_dm": {"label": "КДК % от СВ", "unit": "%"},
"adf_pct_dm_uk": {"label": "КДК % від СВ", "unit": "%"},
"nfc_pct_dm": {"label": "НКВ % от СВ", "unit": "%"},
"nfc_pct_dm_uk": {"label": "НКВ % від СВ", "unit": "%"},
"sw_per_kg_dm": {"label": "SW / кг СВ", "unit": ""},
"fiber_pct_per_kg_dm": {"label": "%СК/кг СВ", "unit": "%"},
"fat_pct_per_kg_dm": {"label": "%-СЖ/кг СВ", "unit": "%"},
"usp_pct_per_kg_dm": {"label": "%-уСП / кг СВ", "unit": "%"},
"ca_pct_per_kg_dm": {"label": "%-Ca / кг СВ", "unit": "%"},
"p_pct_per_kg_dm": {"label": "%-P / кг СВ", "unit": "%"},
"k_pct_per_kg_dm": {"label": "%-К / кг СВ", "unit": "%"},
"na_pct_per_kg_dm": {"label": "%-Na / кг СВ", "unit": "%"},
"mg_pct_per_kg_dm": {"label": "%-Mg / кг СВ", "unit": "%"},
"structural_fiber_pct": {"label": "% стр. клетчатки", "unit": "%"},
"starch_pct_dm": {"label": "% крахмала СВ", "unit": "%"},
"insoluble_starch_pct": {"label": "% нераств. крахмала", "unit": "%"},
"ca_p_ratio": {"label": "Са:P", "unit": ""},
"k_na_ratio": {"label": "K:Na", "unit": ""},
"ration_dm_pct_bw": {"label": "Рацион % СВ от веса", "unit": "%"},
"ration_pct_bw": {"label": "Рацион % от веса", "unit": "%"},
"vitamin_a": {"label": "Витамин А", "unit": "МЕ"},
"vitamin_d": {"label": "Витамин D", "unit": "МЕ"},
"vitamin_e": {"label": "Витамин Е", "unit": "мг"},
"vitamin_b1": {"label": "Витамин В1", "unit": "мг"},
"vitamin_b2": {"label": "Витамин В2", "unit": "мг"},
"vitamin_b6": {"label": "Витамин В6", "unit": "мг"},
"vitamin_b12": {"label": "Витамин В12", "unit": "мкг"},
"calcium_pantothenate": {"label": "Пантотенат кальция", "unit": "мг"},
"niacin": {"label": "Никотиновая к-та", "unit": "мг"},
"folic_acid": {"label": "Фолиевая к-та", "unit": "мг"},
"choline": {"label": "Холин", "unit": "мг"},
"biotin": {"label": "Биотин", "unit": "мкг"},
"iron": {"label": "Fe", "unit": "мг"},
"zinc": {"label": "Zn", "unit": "мг"},
"copper": {"label": "Cu", "unit": "мг"},
"cobalt": {"label": "Co", "unit": "мг"},
"manganese": {"label": "Mn", "unit": "мг"},
"selenium": {"label": "Se", "unit": "мг"},
"iodine": {"label": "J", "unit": "мг"},
"potassium": {"label": "K", "unit": "г"},
"sugar_digestible_starch": {"label": "Сахар и усв. крахмал", "unit": "г"},
"crude_ash": {"label": "Сырая зола", "unit": "г"},
"nfe": {"label": "БЭВ", "unit": "г"},
"arachidonic_acid": {"label": "Арахидоновая к-та", "unit": "г"},
"polyenoic_acid": {"label": "Полиэновая к-та", "unit": "г"},
"oet": {"label": "OET", "unit": ""},
"synthesis_mj": {"label": "Синтез", "unit": "МДж"},
}
_CALC_KEYS = calc_indicator_keys()
def norm_header(value: str) -> str:
return " ".join((value or "").split()).strip()
def norm_title_to_key(title: str) -> str | None:
"""Заголовок колонки CSV → indicator_key (или None)."""
key = NORM_HEADER_TO_KEY.get(norm_header(title))
if key:
return key
return _fallback_key(title)
def _fallback_key(title: str) -> str | None:
n = norm_header(title)
if not n:
return None
low = n.lower().replace("і", "и").replace("є", "е")
for header, key in NORM_HEADER_TO_KEY.items():
if header.lower() == low:
return key
slug = re.sub(r"[^a-z0-9]+", "_", unicodedata.normalize("NFKD", low).encode("ascii", "ignore").decode())
slug = slug.strip("_")[:48]
return f"norm_{slug}" if slug else None
def norm_indicator_meta(key: str) -> dict[str, str | bool]:
calc = _CALC_META.get(key)
if calc:
return {
"key": key,
"label": str(calc["label"]),
"unit": str(calc.get("unit") or ""),
"inCalc": True,
}
extra = _EXTRA_NORM_META.get(key, {})
return {
"key": key,
"label": extra.get("label", key),
"unit": extra.get("unit", ""),
"inCalc": key in _CALC_KEYS,
}
def list_norm_indicators() -> list[dict[str, str | bool]]:
keys: list[str] = []
seen: set[str] = set()
for key in NORM_HEADER_TO_KEY.values():
if key not in seen:
seen.add(key)
keys.append(key)
for key in sorted(_EXTRA_NORM_META):
if key not in seen:
keys.append(key)
return [norm_indicator_meta(k) for k in keys]
def calc_norm_keys() -> frozenset[str]:
return _CALC_KEYS